Objective-C NS_OPTIONS 类型的枚举

本文详细解析Objective-C中的NS_OPTIONS枚举及其在UIViewAutoresizing中的应用,展示了Swift中OptionSet的使用方法。重点讲解了组合与判断技巧,以及如何避免`==`错误地判断枚举成员。同时介绍了Swift中获取枚举数量的方法和技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

NS_OPTIONS 是 Objective-C 中枚举的一种,被定义为按位掩码,可以进行组合枚举表示。用简单的|或者&数据运算来实现整数的编码。

每一个值不是自动被赋予从0开始依次累加1的值,而是手动被赋予一个带有一个bit偏移量的值:类似1 << 01 << 11 << 2等。如果你能够心算出每个数字的二进制表示法,例如:10110 代表 22,每一位都可以被认为是一个单独的布尔值。例如在UIKit中, UIViewAutoresizing 就是一个可以表示任何flexible top、bottom、 left 或 right margins、width、height组合的位掩码。

UIViewAutoresizing

比如UIKit中关于 Autoresizing 的枚举定义:

typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {
    UIViewAutoresizingNone                 = 0,  // 二进制 0000, 十进制0
    UIViewAutoresizingFlexibleLeftMargin   = 1 << 0, // 0001,1
    UIViewAutoresizingFlexibleWidth        = 1 << 1, // 0010,2
    UIViewAutoresizingFlexibleRightMargin  = 1 << 2, // 0100,4
    UIViewAutoresizingFlexibleTopMargin    = 1 << 3, // 1000,8
    UIViewAutoresizingFlexibleHeight       = 1 << 4, // 010000
    UIViewAutoresizingFlexibleBottomMargin = 1 << 5  // 100000
};

而在 Swift 语言环境中,则是使用结构体+类属性 和遵循 OptionSet 来表示

extension UIView {
    struct AutoresizingMask: OptionSet {
        init(rawValue: UInt)

        static var flexibleLeftMargin: UIView.AutoresizingMask
        static var flexibleWidth: UIView.AutoresizingMask
        static var flexibleRightMargin: UIView.AutoresizingMask
        static var flexibleTopMargin: UIView.AutoresizingMask
        static var flexibleHeight: UIView.AutoresizingMask
        static var flexibleBottomMargin: UIView.AutoresizingMask
    }
}

使用

与普通枚举不同,NS_OPTIONS 枚举更加注重组合性,所以使用和判断存在不同

定义枚举变量

使用 | 来组合枚举

UIViewAutoresizing resizing = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;

是否包含

进行枚举检查的时候,我们需要特别注意,千万不要用简单的==,这样不能不能匹配到包含,只能匹配到一个的情况。

== 错误的匹配方式

		UIViewAutoresizing resizing = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    if (resizing == UIViewAutoresizingFlexibleWidth) {
    // resizing = UIViewAutoresizingFlexibleWidth 只有这种情况能匹配成功
    }

& 正确的匹配方式

 		UIViewAutoresizing resizing = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    if (resizing & UIViewAutoresizingFlexibleWidth) {
        NSLog(@"包含 UIViewAutoresizingFlexibleWidth");
    }

结论:NS_OPTIONS 的包含禁止使用 ==

增加选项

使用 |来增加选项

UIViewAutoresizing resizing = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;

减少选项

使用&来减少选项

UIViewAutoresizing resizing = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
resizing = resizing & (~UIViewAutoresizingFlexibleHeight); // 只剩 UIViewAutoresizingFlexibleWidth

参考iOS 混编|为 Objective-C添加枚举宏,改善混编体验,学习如何在 OC中定义字符串枚举。

如何获取 NS_ENUM 数量

在 Swift枚举中可以直接通过方法获取定义了多少个枚举,在 OC中则没有。

定义一个 C 方法

手动返回 count, 记得修改枚举后修改对应值。

 typedef NS_ENUM(NSInteger, MyEnum) { MyEnumA = 0, MyEnumB = 2, MyEnumC = 4, }; NSUInteger MyEnumSize() { return 3; } 

定义一个 count 枚举

不过可以在枚举最后一个定义一个 count,来取巧获取枚举数。如下:
typedef NS_ENUM(NSInteger, MyEnum) {
MyEnumValue1,
MyEnumValue2,
MyEnumValue3,
MyEnumCount
};
不过在switch 语句的时候就很烦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值