当前位置: 首页 > news >正文

理解 iOS 开发中的 NS_ENUM 和 NS_OPTIONS

在开发 iOS 应用程序时,理解 NS_ENUMNS_OPTIONS 的使用至关重要,因为它们在定义和管理枚举和选项方面起着重要作用。在本文中,我们将深入探讨 NS_ENUMNS_OPTIONS 之间的区别、使用场景以及如何有效地实现它们。

NS_ENUM

NS_ENUM 用于定义枚举类型,其中每个枚举值都是互斥的。这意味着一个 NS_ENUM 类型的变量在任何时候只能持有一个值。它通常用于描述状态、类型或分类。

示例:

typedef NS_ENUM(NSInteger, AnimalType) {AnimalTypeDog,AnimalTypeCat,AnimalTypeBird
};

在这个例子中,AnimalType 类型的变量可以是 AnimalTypeDogAnimalTypeCatAnimalTypeBird,但每次只能是其中一个。

使用场景:
NS_ENUM 适用于需要表示一组可能状态中的单一状态的情况。例如,交通灯的颜色、用户角色或支付状态。

示例:

typedef NS_ENUM(NSInteger, TrafficLightState) {TrafficLightStateRed,TrafficLightStateYellow,TrafficLightStateGreen
};TrafficLightState currentState = TrafficLightStateRed;
NS_OPTIONS

NS_OPTIONS 用于定义位掩码枚举类型,其中每个值表示一个独立的位。这允许使用按位操作符组合多个选项。它常用于设置多个标志或选项。

示例:

typedef NS_OPTIONS(NSUInteger, FilePermissions) {FilePermissionRead    = 1 << 0,  // 0001FilePermissionWrite   = 1 << 1,  // 0010FilePermissionExecute = 1 << 2   // 0100
};FilePermissions permissions = FilePermissionRead | FilePermissionWrite; // 0011

在这个例子中,FilePermissions 类型的变量可以同时具有读和写权限。

使用场景:
NS_OPTIONS 适用于需要表示多个组合选项的情况。例如,文件访问权限、UI 组件状态或功能标志。

示例:

typedef NS_OPTIONS(NSUInteger, FilePermissions) {FilePermissionRead    = 1 << 0,  // 0001FilePermissionWrite   = 1 << 1,  // 0010FilePermissionExecute = 1 << 2   // 0100
};FilePermissions permissions = FilePermissionRead | FilePermissionWrite; // 0011// 判断某个权限是否启用
if (permissions & FilePermissionRead) {NSLog(@"Read permission is enabled");
}if (permissions & FilePermissionWrite) {NSLog(@"Write permission is enabled");
}if (permissions & FilePermissionExecute) {NSLog(@"Execute permission is enabled");
} else {NSLog(@"Execute permission is not enabled");
}
组合多个选项

NS_OPTIONS 是通过位掩码实现的,这使得可以组合多个选项。例如,要组合多个文件权限,可以使用按位或操作符 (|):

FilePermissions permissions = FilePermissionRead | FilePermissionWrite; // 0011
判断某个选项是否启用

要判断某个选项是否启用,可以使用按位与操作符 (&)。如果结果不为 0,则表示该选项启用:

if (permissions & FilePermissionRead) {NSLog(@"Read permission is enabled");
}if (permissions & FilePermissionWrite) {NSLog(@"Write permission is enabled");
}if (permissions & FilePermissionExecute) {NSLog(@"Execute permission is enabled");
} else {NSLog(@"Execute permission is not enabled");
}

NS_OPTIONS 的底层实现

NS_OPTIONS 的底层实现是通过定义位掩码值来实现的。每个选项都是一个唯一的位,使用移位操作 (1 << n) 来定义。最终组合起来的值是这些位的按位或结果。

示例代码实现及注释
typedef NS_OPTIONS(NSUInteger, FilePermissions) {FilePermissionRead    = 1 << 0,  // 0001FilePermissionWrite   = 1 << 1,  // 0010FilePermissionExecute = 1 << 2   // 0100
};// 组合权限
FilePermissions permissions = FilePermissionRead | FilePermissionWrite; // 0011// 判断权限
if (permissions & FilePermissionRead) {NSLog(@"Read permission is enabled");
}if (permissions & FilePermissionWrite) {NSLog(@"Write permission is enabled");
}if (permissions & FilePermissionExecute) {NSLog(@"Execute permission is enabled");
} else {NSLog(@"Execute permission is not enabled");
}

关键区别

  1. 互斥性 vs. 组合

    • NS_ENUM 值是互斥的。
    • NS_OPTIONS 值可以通过按位操作符组合。
  2. 使用场景

    • 使用 NS_ENUM 表示一组状态中的单一状态。
    • 使用 NS_OPTIONS 表示一组可组合的选项或标志。
  3. 实现方式

    • NS_ENUM 使用普通的整数值。
    • NS_OPTIONS 使用位移操作定义唯一的位。

结论

理解何时使用 NS_ENUMNS_OPTIONS 对于高效的 iOS 开发至关重要。通过选择合适的方法,你可以编写出更具可读性、可维护性和效率的代码。无论你需要定义一组互斥状态还是一组可组合的选项,NS_ENUMNS_OPTIONS 都提供了必要的工具来处理这些场景。

相关文章:

理解 iOS 开发中的 NS_ENUM 和 NS_OPTIONS

在开发 iOS 应用程序时&#xff0c;理解 NS_ENUM 和 NS_OPTIONS 的使用至关重要&#xff0c;因为它们在定义和管理枚举和选项方面起着重要作用。在本文中&#xff0c;我们将深入探讨 NS_ENUM 和 NS_OPTIONS 之间的区别、使用场景以及如何有效地实现它们。 NS_ENUM NS_ENUM 用…...

2024年6月26日 (周三) 叶子游戏新闻

老板键工具来唤去: 它可以为常用程序自定义快捷键&#xff0c;实现一键唤起、一键隐藏的 Windows 工具&#xff0c;并且支持窗口动态绑定快捷键&#xff08;无需设置自动实现&#xff09;。 土豆录屏: 免费、无录制时长限制、无水印的录屏软件 《Granblue Fantasy Versus: Risi…...

LangChain4j之HelloWorld

什么是LangChain4j 它是Java版本的LangChain&#xff0c;随着大模型的不断发展&#xff0c;如何在程序中更好的利用大模型的能力来提高编程效率是一种趋势&#xff0c;LangChain是这么自己介绍自己的&#xff1a; LangChain gives developers a framework to construct LLM‑p…...

MySQL 基础概念

MySQL逻辑架构 MySQL 服务器逻辑架构图 最上层的服务并不是MySQL所独有的&#xff0c;大多数基于网络的客户端/服务器的工具或者服务都有类似的架构&#xff0c;比如连接管理、授权认证、安全等等。 大多数MySQL的核心服务都在第二层&#xff0c;包括查询解析、分析、优化、…...

RabbitMQ 学习笔记

RabbitMQ学习笔记 一些概念 Broker &#xff1a;RabbitMQ服务。 virtual host&#xff1a; 其实就是分组。 Connection&#xff1a;连接&#xff0c;生产者消费者与Broker之间的TCP连接。 Channel&#xff1a;网络信道&#xff0c;轻量级的Connection&#xff0c;使用Chann…...

【区分vue2和vue3下的element UI MessageBox 弹框组件,分别详细介绍属性,事件,方法如何使用,并举例】

在 Vue 2 中&#xff0c;Element UI 提供了 MessageBox 弹框组件&#xff0c;用于显示消息提示、确认消息和获取用户输入等。而在 Vue 3 的 Element Plus 中&#xff0c;虽然组件和 API 可能有所变化&#xff0c;但基本概念和用法是相似的。下面我将分别介绍 Vue 2 的 Element …...

避而不见!BigDecimal的四大坑

BigDecimal概述 定义&#xff1a;Java中的类&#xff0c;用于表示任意精度的十进制数。适用场景&#xff1a;需要高精度计算的场合&#xff0c;如金融、货币、税收等。 一、浮点精度的坑 问题&#xff1a;使用BigDecimal的equals和compareTo方法比较数值时&#xff0c;存在精…...

IDEA 安装与激活详细教程最新(附最新激活码)2099年亲测有效!

我们先从 IDEA 官网下载 IDEA 2024.1 版本的安装包&#xff0c;下载链接如下&#xff1a; https://www.jetbrains.com/idea/download/ 点击下载(下载Ultimate版)&#xff0c;静心等待其下载完毕即可。 激活方式&#xff1a; 正版专属激活码领取...

LeetCode 100334. 包含所有 1 的最小矩形面积 I

更多题解尽在 https://sugar.matrixlab.dev/algorithm 每日更新。 组队打卡&#xff0c;更多解法等你一起来参与哦&#xff01; LeetCode 100334. 包含所有 1 的最小矩形面积 I&#xff0c;难度中等。 遍历 解题思路&#xff1a;去掉矩形上下左右全为 0 的行和列 class Solu…...

pdf只要前几页,pdf怎么只要前几页

在现代办公和学习环境中&#xff0c;PDF文件已成为我们日常处理信息的重要工具。然而&#xff0c;有时我们并不需要整个PDF文件的内容&#xff0c;而只是其中的几页。那么&#xff0c;如何高效地提取PDF文件中的特定页面呢&#xff1f;本文将为您介绍几种实用的方法。 打开 “ …...

JAVA JVM 是怎么判定对象已经“死去”?

Java虚拟机&#xff08;JVM&#xff09;使用垃圾收集&#xff08;Garbage Collection&#xff0c;GC&#xff09;机制来自动管理内存&#xff0c;其中包括识别和回收不再使用的对象。JVM判定对象已经“死去”&#xff08;即不再被任何引用所指向&#xff09;的过程主要基于以下…...

springboot加载注入bean的方式

在SpringBoot的大环境下&#xff0c;基本上很少使用之前的xml配置Bean&#xff0c;主要是因为这种方式不好维护而且也不够方便。 springboto注入bean主要采用下图几种方式&#xff0c;分为本地服务工程注解声明的bean和外部依赖包中的bean。 一、 springboot装配本地服务工程…...

PostgreSQL 数据库设计与管理(四)

1. 数据库设计原则 1.1 规范化 规范化是组织数据库结构的一种方法&#xff0c;旨在减少数据冗余并提高数据完整性。常用的规范化范式包括&#xff1a; 第一范式&#xff08;1NF&#xff09;&#xff1a; 确保每列都是原子的&#xff0c;不可再分。第二范式&#xff08;2NF&a…...

Studying-代码随想录训练营day21| 669.修建二叉搜索树、108.将有序数组转换为二叉搜索树、538.把二叉搜索树转换为累加树、二叉树总结

第21天&#xff0c;二叉树最后一篇&#xff0c;冲&#x1f4aa; 目录 669.修建二叉搜索树 108.将有序数组转换为二叉搜索树 538.把二叉搜索树转换为累加树 二叉树总结 669.修建二叉搜索树 文档讲解&#xff1a;代码随想录修建二叉搜索树 视频讲解&#xff1a;手撕修建二叉…...

GraphQL:简介

GraphQL 图片来源&#xff1a; 我们将探索GraphQL 的基础知识&#xff0c;并学习如何使用Apollo将其与 React 和 React Native 等前端框架连接起来。这将帮助您了解如何使用 GraphQL、React、React Native 和 Apollo 构建现代、高效的应用程序。 什么是 GraphQL&#xff1f;…...

AI大模型安全挑战和安全要求解读

引言 随着人工智能技术的飞速发展&#xff0c;大模型技术以其卓越的性能和广泛的应用前景&#xff0c;正在重塑人工智能领域的新格局。然而&#xff0c;任何技术都有两面性&#xff0c;大模型在带来前所未有便利的同时&#xff0c;也引发了深刻的安全和伦理挑战。 大模型&…...

前端面试题-token的存放位置

哈喽小伙伴们大家好,本系列是一个专门针对前端开发岗的面试题系列,每周将会不定期分享一些面试题,希望对大家有所帮助. 面试官:token 一般在客户端存在哪儿 求职者:Token一般在客户端存在以下几个地方&#xff1a; (1)Cookie&#xff1a;Token可以存储在客户端的Cookie中。服…...

深入探讨计算机网络中的各种报文

在计算机网络中&#xff0c;报文&#xff08;Packet&#xff09;是数据传输的基本单位。不同的协议使用不同类型的报文来实现数据传输的各种功能。本文将详细探讨计算机网络中常见的几种报文类型&#xff0c;并通过举例说明其具体应用。 一、TCP/IP协议栈中的报文 TCP/IP协议…...

Debezium系列之:Mysql和SQLServer数据库字段类型覆盖测试

Debezium系列之:Mysql和SQLServer数据库字段类型覆盖测试 一、需求背景二、类型对比三、完整流程三、Mysql数据库全字段类型覆盖测试四、SQLServer数据库字段类型覆盖测试一、需求背景 Debezium版本升级迭代,要做字段类型测试,确保版本间字段类型的差异下游能够自动适应,或…...

Mathtype7在Word2016中闪退(安装过6)

安装教程&#xff1a;https://blog.csdn.net/Little_pudding10/article/details/135465291 Mathtype7在Word2016中闪退是因为安装过Mathtype6&#xff0c;MathPage.wll和MathType Comm***.dotm)&#xff0c;不会随着Mathtype的删除自动删除&#xff0c;而新版的Mathtype中的文件…...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...

Spring是如何解决Bean的循环依赖:三级缓存机制

1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间‌互相持有对方引用‌,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

虚拟电厂发展三大趋势:市场化、技术主导、车网互联

市场化&#xff1a;从政策驱动到多元盈利 政策全面赋能 2025年4月&#xff0c;国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》&#xff0c;首次明确虚拟电厂为“独立市场主体”&#xff0c;提出硬性目标&#xff1a;2027年全国调节能力≥2000万千瓦&#xff0…...

STM32HAL库USART源代码解析及应用

STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing

Muffin 论文 现有方法 CRADLE 和 LEMON&#xff0c;依赖模型推理阶段输出进行差分测试&#xff0c;但在训练阶段是不可行的&#xff0c;因为训练阶段直到最后才有固定输出&#xff0c;中间过程是不断变化的。API 库覆盖低&#xff0c;因为各个 API 都是在各种具体场景下使用。…...

十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建

【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...