在Objective-C中声明和检查/比较(bitmask-)枚举
你知道在cocoa有这个东西,例如你可以创build一个UIView
并做:
view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
我有一个自定义的UIView
与多个状态,我已经在这样的enum
定义:
enum DownloadViewStatus { FileNotDownloaded, FileDownloading, FileDownloaded };
对于每个创build的子视图,我设置它的tag
: subview1.tag = FileNotDownloaded;
然后,我有一个自定义setter的视图状态,它执行以下操作:
for (UIView *subview in self.subviews) { if (subview.tag == viewStatus) subview.hidden = NO; else subview.hidden = YES; }
但是我想要做的是让这个:
subview1.tag = FileNotDownloaded | FileDownloaded;
所以我的subview1
出现在我的观点的两个状态。 目前,它并没有出现在这两个州以来的任何一个州 运算符似乎添加了两个枚举值。
有没有办法做到这一点?
声明位掩码:
或者分配绝对值( 4
,…),您可以声明位掩码 (如何调用):
typedef enum : NSUInteger { FileNotDownloaded = (1 << 0), // => 00000001 FileDownloading = (1 << 1), // => 00000010 FileDownloaded = (1 << 2) // => 00000100 } DownloadViewStatus;
或者使用现代的ObjC的NS_OPTIONS
/ NS_ENUM
macros:
typedef NS_OPTIONS(NSUInteger, DownloadViewStatus) { FileNotDownloaded = (1 << 0), // => 00000001 FileDownloading = (1 << 1), // => 00000010 FileDownloaded = (1 << 2) // => 00000100 };
(有关后者的更多信息,请参阅Abizern的答案 )
位掩码的概念是(通常)用一个位集来定义每个枚举值。
因此, OR
两个值做以下操作:
DownloadViewStatus status = FileNotDownloaded | FileDownloaded; // => 00000101
相当于:
00000001 // FileNotDownloaded | 00000100 // FileDownloaded ---------- = 00000101 // (FileNotDownloaded | FileDownloaded)
比较位掩码:
检查位掩码时要记住一件事情:
检查确切的平等:
假设状态是这样初始化的:
DownloadViewStatus status = FileNotDownloaded | FileDownloaded; // => 00000101
如果你想检查status
等于 FileNotDownloaded
,你可以使用:
BOOL equals = (status == FileNotDownloaded); // => false
相当于:
00000101 // (FileNotDownloaded | FileDownloaded) == 00000100 // FileDownloaded ----------- = 00000000 // false
检查“成员资格”:
如果你想检查status
只包含 FileNotDownloaded
,你需要使用:
BOOL contains = (status & FileNotDownloaded) != 0; // => true 00000101 // (FileNotDownloaded | FileDownloaded) & 00000100 // FileDownloaded ----------- = 00000100 // FileDownloaded != 00000000 // 0 ----------- = 00000001 // 1 => true
看到微妙的差异(以及为什么你目前的“如果”expression可能是错误的)?
虽然@Regexident提供了一个很好的答案 – 我必须提到用NS_OPTIONS
声明枚举选项的现代Objective-C方法:
typedef NS_OPTIONS(NSUInteger, DownloadViewStatus) { FileNotDownloaded = 0, FileDownloading = 1 << 0, FileDownloaded = 1 << 1 };
进一步参考:
- NSHipster
- 我是海象
enum DownloadViewStatus { FileNotDownloaded = 1, FileDownloading = 2, FileDowloaded = 4 };
这将使您可以有效地执行按位OR和AND。