你知道在Cocoa有这个东西,例如你可以创建一个UIView
并做:
view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
我有一个有多个状态的自定义UIView
,我已在enum
中定义如下:
enum DownloadViewStatus {
FileNotDownloaded,
FileDownloading,
FileDownloaded
};
对于每个创建的子视图,我设置了它的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
出现在我看来的两个状态。目前,由于|
运算符似乎添加了两个枚举值,因此它不会出现在这两个状态中的任何一个状态中。
有没有办法做到这一点?
或者指定绝对值(1
,2
,4
,...)你可以像这样声明bitmasks(如何调用它们):
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's answer)
位掩码的概念是(通常)用单个位集定义每个枚举值。
因此,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
看到微妙的差异(以及为什么你当前的“如果” - 表达可能是错误的)?
虽然@Regexident提供了一个很好的答案 - 我必须提到使用NS_OPTIONS
声明枚举选项的现代Objective-C方法:
typedef NS_OPTIONS(NSUInteger, DownloadViewStatus) {
FileNotDownloaded = 0,
FileDownloading = 1 << 0,
FileDownloaded = 1 << 1
};
进一步参考:
enum DownloadViewStatus {
FileNotDownloaded = 1,
FileDownloading = 2,
FileDowloaded = 4
};
这将让您有效地执行按位OR和AND。
可用于进行位掩码检查以提高可读性的有用功能。
BOOL bitmaskContains(NSUInteger bitmask, NSUInteger contains) {
return (bitmask & contains) != 0;
}