声明位掩码:
除了分配绝对值(1
, 2
, 4
, ...),您还可以像这样声明位掩码(如何调用它们):
typedef enum : NSUInteger {
FileNotDownloaded = (1 << 0), // => 00000001
FileDownloading = (1 << 1), // => 00000010
FileDownloaded = (1 << 2) // => 00000100
} DownloadViewStatus;
或使用现代 ObjC 的NS_OPTIONS
/NS_ENUM
宏:
typedef NS_OPTIONS(NSUInteger, DownloadViewStatus) {
FileNotDownloaded = (1 << 0), // => 00000001
FileDownloading = (1 << 1), // => 00000010
FileDownloaded = (1 << 2) // => 00000100
};
(有关后者的更多信息,请参阅Abizern 的回答)
位掩码的概念是(通常)用单个位集定义每个枚举值。
因此OR
ing 两个值执行以下操作:
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
看到细微的差别(以及为什么您当前的“if”表达式可能是错误的)?