ios/object-c enum,NS_ENUM,NS_OPTIONS

本文深入探讨了iOS开发中枚举类型和位运算的应用,包括定义枚举、位移操作以及如何在代码中高效利用这些特性。详细介绍了NS_OPTIONS宏的作用,与通用NS_ENUM的区别,以及如何在实际项目中灵活运用枚举和位运算来简化代码逻辑。
Wan2.2-T2V-A5B

Wan2.2-T2V-A5B

文生视频
Wan2.2

Wan2.2是由通义万相开源高效文本到视频生成模型,是有​50亿参数的轻量级视频生成模型,专为快速内容创作优化。支持480P视频生成,具备优秀的时序连贯性和运动推理能力

一般情况下,我们采用C风格的enum关键字可以定义枚举类型。

 

  1. enum{   
  2.     UIViewAnimationTransitionNone,  
  3.     UIViewAnimationTransitionFlipFromLeft,  
  4.     UIViewAnimationTransitionFlipFromRight,  
  5.     UIViewAnimationTransitionCurlUp,  
  6.     UIViewAnimationTransitionCurlDown,  
  7. } UIViewAnimationTransition;  
  1. //位移操作枚举定义  
  2. enum {  
  3.     UIViewAutoresizingNone                 = 0,  
  4.     UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,  
  5.     UIViewAutoresizingFlexibleWidth        = 1 << 1,  
  6.     UIViewAutoresizingFlexibleRightMargin  = 1 << 2,  
  7.     UIViewAutoresizingFlexibleTopMargin    = 1 << 3,  
  8.     UIViewAutoresizingFlexibleHeight       = 1 << 4,  
  9.     UIViewAutoresizingFlexibleBottomMargin = 1 << 5  
  10. };  
  11. typedef NSUInteger UIViewAutoresizing;//使用NSUInteger的地方可以使用UIViewAutoresizing,//UIViewAutoresizing相当于NSUInteger的一个别名使用。  
  12. //因此一个UIViewAutoresizing的变量可以直接赋值给NSUInteger  

枚举值一般是4个字节的int值,在64位系统上是8个字节。

在iOS6和Mac OS 10.8以后Apple引入了两个宏来重新定义这两个枚举类型,实际上是将enum定义和typedef合二为一,并且采用不同的宏来从代码角度来区分。

NS_OPTIONS一般用来定义位移相关操作的枚举值,我们可以参考UIKit.Framework的头文件,可以看到大量的枚举定义。

 

  1. typedef NS_ENUM(NSInteger, UIViewAnimationTransition) {  
  2.     UIViewAnimationTransitionNone,//默认从0开始  
  3.     UIViewAnimationTransitionFlipFromLeft,  
  4.     UIViewAnimationTransitionFlipFromRight,  
  5.     UIViewAnimationTransitionCurlUp,  
  6.     UIViewAnimationTransitionCurlDown,  
  7. };  
  8.   
  9. typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {  
  10.     UIViewAutoresizingNone                 = 0,  
  11.     UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,  
  12.     UIViewAutoresizingFlexibleWidth        = 1 << 1,  
  13.     UIViewAutoresizingFlexibleRightMargin  = 1 << 2,  
  14.     UIViewAutoresizingFlexibleTopMargin    = 1 << 3,  
  15.     UIViewAutoresizingFlexibleHeight       = 1 << 4,  
  16.     UIViewAutoresizingFlexibleBottomMargin = 1 << 5  
  17. }; 

从枚举定义来看,NS_ENUM和NS_OPTIONS本质是一样的,仅仅从字面上来区分其用途。NS_ENUM是通用情况,NS_OPTIONS一般用来定义具有位移操作或特点的情况(bitmask)。 


枚举值 它是一个整形(int) 并且,它不参加内存的占用和释放 枚举定义变量即可直接使用,不用初始化. 枚举的定义如下:

typedef enum {

//以下是枚举成员 TestA = 0,

    TestB,  

    TestC,  

    TestD 

}Test;//枚举名称

亦可以如下定义(推荐:结构比较清晰):

typedef NS_ENUM(NSInteger, Test1) {

//以下是枚举成员

    Test1A = 0,

    Test1B = 1,

    Test1C = 2,

    Test1D = 3

};

 

枚举的定义还支持位运算的方式定义,如下: 等于号后面必须等于1

typedef NS_ENUM(NSInteger, Test) {

    TestA = 1, //1 1 1

    TestB = 1 << 1, //2 2 10 转换成 10进制 2

    TestC = 1 << 2, //4 3 100 转换成 10进制 4

    TestD = 1 << 3, //8 4 1000 转换成 10进制 8

    TestE = 1 << 4 //16 5 10000 转换成 10进制 16

};

什么时候要用到这种方式呢? 那就是一个枚举变量可能要代表多个枚举值的时候. 其实给一个枚举变量赋予多个枚举值的时候,原理只是把各个枚举值加起来罢了. 当加起来以后,就获取了一个新的值,那么为了保证这个值的唯一性,这个时候就体现了位运算的重要作用. 位运算可以确保枚举值组合的唯一性. 因为位运算的计算方式是将二进制转换成十进制,也就是说,枚举值里面存取的是 计算后的十进制值. 打个比方: 通过上面的位运算方式设定好枚举以后,打印出来的枚举值分别是: 1 2 4 8 16 这5个数字,无论你如何组合在一起,也不会产生两个同样的数字.

您可能感兴趣的与本文相关的镜像

Wan2.2-T2V-A5B

Wan2.2-T2V-A5B

文生视频
Wan2.2

Wan2.2是由通义万相开源高效文本到视频生成模型,是有​50亿参数的轻量级视频生成模型,专为快速内容创作优化。支持480P视频生成,具备优秀的时序连贯性和运动推理能力

FAILED: contrib/magister-stats/CMakeFiles/libmagister-stats-obj.dir/model/distribution-collector.cc.o /usr/bin/ccache /usr/bin/c++ -DHAVE_GSL -DHAVE_LIBXML2 -DHAVE_SQLITE3 -DNS3_BUILD_PROFILE_OPTIMIZED -DPROJECT_SOURCE_PATH=\"/home/df/ns3/ns-allinone-3.37/ns-3.37\" -D__LINUX__ -I/usr -I/home/df/ns3/ns-allinone-3.37/ns-3.37/build/include -I/usr/include/freetype2 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/gtk-3.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/harfbuzz -I/usr/include/atk-1.0 -I/usr/include/libxml2 -I/usr/include/python3.10 -I/home/df/Anaconda3/include -O3 -DNDEBUG -fPIC -fno-semantic-interposition -fdiagnostics-color=always -Wall -march=native -mtune=native -std=gnu++17 -Winvalid-pch -include /home/df/ns3/ns-allinone-3.37/ns-3.37/cmake-cache/CMakeFiles/stdlib_pch.dir/cmake_pch.hxx -MD -MT contrib/magister-stats/CMakeFiles/libmagister-stats-obj.dir/model/distribution-collector.cc.o -MF contrib/magister-stats/CMakeFiles/libmagister-stats-obj.dir/model/distribution-collector.cc.o.d -o contrib/magister-stats/CMakeFiles/libmagister-stats-obj.dir/model/distribution-collector.cc.o -c /home/df/ns3/ns-allinone-3.37/ns-3.37/contrib/magister-stats/model/distribution-collector.cc /home/df/ns3/ns-allinone-3.37/ns-3.37/contrib/magister-stats/model/distribution-collector.cc: In static member function ‘static ns3::TypeId ns3::DistributionCollector::GetTypeId()’: /home/df/ns3/ns-allinone-3.37/ns-3.37/contrib/magister-stats/model/distribution-collector.cc:120:68: error: no matching function for call to ‘MakeEnumAccessor<ns3::DistributionCollector::OutputType_t>(void (ns3::DistributionCollector::*)(ns3::DistributionCollector::OutputType_t), ns3::DistributionCollector::OutputType_t (ns3::DistributionCollector::*)() const)’ 120 | &DistributionCollector::GetOutputType), | ^ In file included from /home/df/ns3/ns-allinone-3.37/ns-3.37/build/include/ns3/enum.h:1, from /home/df/ns3/ns-allinone-3.37/ns-3.37/contrib/magister-stats/model/distribution-collector.cc:29: /home/df/ns3/ns-allinone-3.37/ns-3.37/src/core/model/enum.h:205:1: note: candidate: ‘ns3::Ptr<const ns3::AttributeAccessor> ns3::MakeEnumAccessor(T1) [with T1 = ns3::DistributionCollector::OutputType_t]’ 205 | MakeEnumAccessor(T1 a1) | ^~~~~~~~~~~~~~~~ /home/df/ns3/ns-allinone-3.37/ns-3.37/src/core/model/enum.h:205:1: note: candidate expects 1 argument, 2 provided /home/df/ns3/ns-allinone-3.37/ns-3.37/src/core/model/enum.h:212:1: note: candidate: ‘template<class T1, class T2> ns3::Ptr<const ns3::AttributeAccessor> ns3::MakeEnumAccessor(T1, T2)’ 212 | MakeEnumAccessor(T1 a1, T2 a2) | ^~~~~~~~~~~~~~~~ /home/df/ns3/ns-allinone-3.37/ns-3.37/src/core/model/enum.h:212:1: note: template argument deduction/substitution failed: /home/df/ns3/ns-allinone-3.37/ns-3.37/contrib/magister-stats/model/distribution-collector.cc:119:31: note: cannot convert ‘&ns3::DistributionCollector::SetOutputType’ (type ‘void (ns3::DistributionCollector::*)(ns3::DistributionCollector::OutputType_t)’) to type ‘ns3::DistributionCollector::OutputType_t’ 119 | &DistributionCollector::SetOutputType, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home/df/ns3/ns-allinone-3.37/ns-3.37/contrib/magister-stats/model/distribution-collector.cc:132:65: error: no matching function for call to ‘MakeEnumAccessor<ns3::DistributionCollector::DistributionBinType_t>(void (ns3::DistributionCollector::*)(ns3::DistributionCollector::DistributionBinType_t), ns3::DistributionCollector::DistributionBinType_t (ns3::DistributionCollector::*)() const)’ 132 | &DistributionCollector::GetBinType), | ^ In file included from /home/df/ns3/ns-allinone-3.37/ns-3.37/build/include/ns3/enum.h:1, from /home/df/ns3/ns-allinone-3.37/ns-3.37/contrib/magister-stats/model/distribution-collector.cc:29: /home/df/ns3/ns-allinone-3.37/ns-3.37/src/core/model/enum.h:205:1: note: candidate: ‘ns3::Ptr<const ns3::AttributeAccessor> ns3::MakeEnumAccessor(T1) [with T1 = ns3::DistributionCollector::DistributionBinType_t]’ 205 | MakeEnumAccessor(T1 a1) | ^~~~~~~~~~~~~~~~ /home/df/ns3/ns-allinone-3.37/ns-3.37/src/core/model/enum.h:205:1: note: candidate expects 1 argument, 2 provided /home/df/ns3/ns-allinone-3.37/ns-3.37/src/core/model/enum.h:212:1: note: candidate: ‘template<class T1, class T2> ns3::Ptr<const ns3::AttributeAccessor> ns3::MakeEnumAccessor(T1, T2)’ 212 | MakeEnumAccessor(T1 a1, T2 a2) | ^~~~~~~~~~~~~~~~ /home/df/ns3/ns-allinone-3.37/ns-3.37/src/core/model/enum.h:212:1: note: template argument deduction/substitution failed: /home/df/ns3/ns-allinone-3.37/ns-3.37/contrib/magister-stats/model/distribution-collector.cc:131:31: note: cannot convert ‘&ns3::DistributionCollector::SetBinType’ (type ‘void (ns3::DistributionCollector::*)(ns3::DistributionCollector::DistributionBinType_t)’) to type ‘ns3::DistributionCollector::DistributionBinType_t’ 131 | &DistributionCollector::SetBinType, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [9/2359] Building CXX object contrib/m...j.dir/model/multi-file-aggregator.cc.o FAILED: contrib/magister-stats/CMakeFiles/libmagister-stats-obj.dir/model/multi-file-aggregator.cc.o /usr/bin/ccache /usr/bin/c++ -DHAVE_GSL -DHAVE_LIBXML2 -DHAVE_SQLITE3 -DNS3_BUILD_PROFILE_OPTIMIZED -DPROJECT_SOURCE_PATH=\"/home/df/ns3/ns-allinone-3.37/ns-3.37\" -D__LINUX__ -I/usr -I/home/df/ns3/ns-allinone-3.37/ns-3.37/build/include -I/usr/include/freetype2 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/gtk-3.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/harfbuzz -I/usr/include/atk-1.0 -I/usr/include/libxml2 -I/usr/include/python3.10 -I/home/df/Anaconda3/include -O3 -DNDEBUG -fPIC -fno-semantic-interposition -fdiagnostics-color=always -Wall -march=native -mtune=native -std=gnu++17 -Winvalid-pch -include /home/df/ns3/ns-allinone-3.37/ns-3.37/cmake-cache/CMakeFiles/stdlib_pch.dir/cmake_pch.hxx -MD -MT contrib/magister-stats/CMakeFiles/libmagister-stats-obj.dir/model/multi-file-aggregator.cc.o -MF contrib/magister-stats/CMakeFiles/libmagister-stats-obj.dir/model/multi-file-aggregator.cc.o.d -o contrib/magister-stats/CMakeFiles/libmagister-stats-obj.dir/model/multi-file-aggregator.cc.o -c /home/df/ns3/ns-allinone-3.37/ns-3.37/contrib/magister-stats/model/multi-file-aggregator.cc /home/df/ns3/ns-allinone-3.37/ns-3.37/contrib/magister-stats/model/multi-file-aggregator.cc: In static member function ‘static ns3::TypeId ns3::MultiFileAggregator::GetTypeId()’: /home/df/ns3/ns-allinone-3.37/ns-3.37/contrib/magister-stats/model/multi-file-aggregator.cc:71:98: error: no matching function for call to ‘MakeEnumAccessor<ns3::MultiFileAggregator::FileType>(void (ns3::MultiFileAggregator::*)(ns3::MultiFileAggregator::FileType))’ 71 | MakeEnumAccessor<MultiFileAggregator::FileType>(&MultiFileAggregator::SetFileType), | ^ In file included from /home/df/ns3/ns-allinone-3.37/ns-3.37/build/include/ns3/enum.h:1, from /home/df/ns3/ns-allinone-3.37/ns-3.37/contrib/magister-stats/model/multi-file-aggregator.cc:33: /home/df/ns3/ns-allinone-3.37/ns-3.37/src/core/model/enum.h:205:1: note: candidate: ‘ns3::Ptr<const ns3::AttributeAccessor> ns3::MakeEnumAccessor(T1) [with T1 = ns3::MultiFileAggregator::FileType]’ 205 | MakeEnumAccessor(T1 a1) | ^~~~~~~~~~~~~~~~ /home/df/ns3/ns-allinone-3.37/ns-3.37/src/core/model/enum.h:205:21: note: no known conversion for argument 1 from ‘void (ns3::MultiFileAggregator::*)(ns3::MultiFileAggregator::FileType)’ to ‘ns3::MultiFileAggregator::FileType’ 205 | MakeEnumAccessor(T1 a1) | ~~~^~ /home/df/ns3/ns-allinone-3.37/ns-3.37/src/core/model/enum.h:212:1: note: candidate: ‘template<class T1, class T2> ns3::Ptr<const ns3::AttributeAccessor> ns3::MakeEnumAccessor(T1, T2)’ 212 | MakeEnumAccessor(T1 a1, T2 a2) | ^~~~~~~~~~~~~~~~ /home/df/ns3/ns-allinone-3.37/ns-3.37/src/core/model/enum.h:212:1: note: template argument deduction/substitution failed: /home/df/ns3/ns-allinone-3.37/ns-3.37/contrib/magister-stats/model/multi-file-aggregator.cc:71:98: note: candidate expects 2 arguments, 1 provided 71 | MakeEnumAccessor<MultiFileAggregator::FileType>(&MultiFileAggregator::SetFileType), | ^ [19/2359] Building CXX object contrib/...ir/helper/stats-throughput-helper.cc.o ninja: build stopped: subcommand failed. Finished executing the following commands: cd cmake-cache; cmake --build . -j 15 ; cd ..
05-16
### 解决 `MakeEnumAccessor` 函数调用错误的问题 在 NS-3.37 中,如果遇到 `MakeEnumAccessor` 调用错误的情况,通常是因为枚举类型的定义或者访问器的设置存在问题。以下是可能的原因以及解决方案: #### 可能原因分析 1. **枚举类型未正确定义** 如果 `OutputType_t` 或其他相关枚举类型(如 `DistributionBinType_t`)未被正确声明,则可能导致编译失败或运行时错误。需要确认这些枚举类型是否已在头文件中明确定义[^1]。 2. **属性注册不匹配** 使用 `MakeEnumAccessor` 需要确保对象的成员变量与对应的 getter 和 setter 方法相匹配。如果成员变量是一个枚举类型,那么其 getter 和 setter 的签名也应与此一致[^2]。 3. **缺少必要的依赖项** 如引用[2]提到,在处理复杂模块(如卫星通信模块 satellite)时,需确保所有必要组件已安装并配置妥当。例如,某些功能可能依赖于特定的数据包或插件,若缺失则可能出现各种异常行为。 4. **C++标准版本冲突** 若项目使用的 C++ 编译选项不符合预期(比如 `-std=c++17` vs `-std=c++14`),也可能引发类似的错误消息。建议检查构建脚本中的编译参数设置是否统一[^1]。 #### 实际案例修复方案 假设存在如下代码片段: ```cpp enum class OutputType_t { FILE, STREAM, }; class ExampleClass : public Object { public: static TypeId GetTypeId(void); private: OutputType_t m_outputType; }; ``` 此时可以这样实现 `GetTypeId()` 方法: ```cpp TypeId ExampleClass::GetTypeId(void) { static TypeId tid = TypeId("ExampleClass") .SetParent<Object>() .AddAttribute( "OutputType", "The type of output to use.", EnumValue(OutputType_t::FILE), MakeEnumAccessor(&ExampleClass::m_outputType), // 关键部分 MakeEnumChecker<OutputType_t>( {OutputType_t::FILE, OutputType_t::STREAM}) ); return tid; } ``` 以上代码通过 `MakeEnumAccessor` 将私有成员变量绑定到公共接口,并利用 `MakeEnumChecker` 提供合法值范围验证机制。 #### 注意事项 - 确认所有的自定义数据结构均已包含适当构造函数及析构函数; - 对于第三方库集成场景下,请参照官方文档完成初始化流程; - 当调试难以定位具体位置时,尝试启用更详细的日志记录或将问题隔离至最小化重现单元测试环境中进一步排查。 ```python # 示例 Python 版本辅助工具用于生成 ns-3 枚举映射表 (仅作参考用途) def generate_enum_mapping(enum_class_name, values_list): mapping_str = f"class {enum_class_name}:\n" for idx, val in enumerate(values_list): mapping_str += f" {val.upper()} = {idx}\n" return mapping_str print(generate_enum_mapping('FileType', ['txt', 'csv'])) ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值