在Objective-C中声明和检查/比较(bitmask-)枚举

你知道在cocoa有这个东西,例如你可以创build一个UIView并做:

 view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 

我有一个自定义的UIView与多个状态,我已经在这样的enum定义:

 enum DownloadViewStatus { FileNotDownloaded, FileDownloading, FileDownloaded }; 

对于每个创build的子视图,我设置它的tagsubview1.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。