声明和检查/在Objective-C对比(bitmask-)枚举 [英] Declaring and checking/comparing (bitmask-)enums in Objective-C

查看:146
本文介绍了声明和检查/在Objective-C对比(bitmask-)枚举的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您知道可可有这个东西,比如你可以创建一个的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 ORing 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆