声明和检查/在Objective-C对比(bitmask-)枚举 [英] Declaring and checking/comparing (bitmask-)enums in Objective-C
问题描述
您知道可可有这个东西,比如你可以创建一个的UIView
然后执行:
You know in Cocoa there is this thing, for example you can create a UIView
and do:
view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
我有一个自定义的的UIView
具有多种状态,这是我在定义枚举
是这样的:
I have a custom UIView
with multiple states, which I have defined in an enum
like this:
enum DownloadViewStatus {
FileNotDownloaded,
FileDownloading,
FileDownloaded
};
有关每个创建子视图,我设置了标记
: subview1.tag = FileNotDownloaded;
For each created subview, I set its tag
: subview1.tag = FileNotDownloaded;
然后,我有哪些呢下面的视图状态的自定义的setter:
Then, I have a custom setter for the view state which does the following:
for (UIView *subview in self.subviews) {
if (subview.tag == viewStatus)
subview.hidden = NO;
else
subview.hidden = YES;
}
但什么,我试图做,是为了让这样的:
subview1.tag = FileNotDownloaded | FileDownloaded;
所以,我的 subview1
在我看来,两种状态显示出来。目前,它不以任何这两个国家因为显示|
运营商似乎添加两个枚举值。
So my subview1
shows up in two states of my view. Currently, it doesn't show up in any of those two states since the |
operator seems to add the two enum values.
有没有办法做到这一点?
Is there a way to do that?
推荐答案
或者到指定的绝对值( 1
, 2
, 4
......),你可以声明 位掩码 (这些都是怎么叫)所示:
Declaring Bitmasks:
Alternatively to assigning absolute values (1
, 2
, 4
, …) you can declare bitmasks (how these are called) like this:
typedef enum : NSUInteger {
FileNotDownloaded = (1 << 0), // => 00000001
FileDownloading = (1 << 1), // => 00000010
FileDownloaded = (1 << 2) // => 00000100
} DownloadViewStatus;
或利用现代ObjC的 NS_OPTIONS
/ NS_ENUM
宏:
or using modern ObjC's NS_OPTIONS
/NS_ENUM
macros:
typedef NS_OPTIONS(NSUInteger, DownloadViewStatus) {
FileNotDownloaded = (1 << 0), // => 00000001
FileDownloading = (1 << 1), // => 00000010
FileDownloaded = (1 << 2) // => 00000100
};
(见 Abizern的回答以对后者详细信息)
位掩码的概念是(通常)用一个位设置定义每个枚举值。
The concept of bitmasks is to (usually) define each enum value with a single bit set.
因此,或
ING两个值执行以下操作:
Hence OR
ing two values does the following:
DownloadViewStatus status = FileNotDownloaded | FileDownloaded; // => 00000101
这相当于:
00000001 // FileNotDownloaded
| 00000100 // FileDownloaded
----------
= 00000101 // (FileNotDownloaded | FileDownloaded)
对比位掩码:
有一件事对位掩码检查时,要记住:
Comparing Bitmasks:
One thing to keep in mind when checking against bitmasks:
让我们假设状态像这样初始化的:
Let's assume that status is initialized like this:
DownloadViewStatus status = FileNotDownloaded | FileDownloaded; // => 00000101
如果你想检查是否状态
等于 FileNotDownloaded
,你可以使用:
If you want to check if status
equals FileNotDownloaded
, you can use:
BOOL equals = (status == FileNotDownloaded); // => false
这相当于:
00000101 // (FileNotDownloaded | FileDownloaded)
== 00000100 // FileDownloaded
-----------
= 00000000 // false
检查会员制:
如果你想检查是否状态
仅仅包含 FileNotDownloaded
,你需要使用方法:
Checking for "membership":
If you want to check if status
merely contains FileNotDownloaded
, you need to use:
BOOL contains = (status & FileNotDownloaded) != 0; // => true
00000101 // (FileNotDownloaded | FileDownloaded)
& 00000100 // FileDownloaded
-----------
= 00000100 // FileDownloaded
!= 00000000 // 0
-----------
= 00000001 // 1 => true
请参阅的细微差别(为什么你目前的如果-ex pression可能是错的)?
See the subtle difference (and why your current "if"-expression is probably wrong)?
这篇关于声明和检查/在Objective-C对比(bitmask-)枚举的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!