在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_ENUMmacros: 
 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。