iOS框架类中的C枚举定义

4

我正在浏览UIKit框架的头文件,看到很多匿名枚举被定义,紧接着是一个看似相关的typedef。请问这里发生了什么?

UIViewAutoresizing类型是否(隐式地)引用了前面声明的枚举?你如何引用该枚举类型?

enum {
    UIViewAutoresizingNone                 = 0,
    UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,
    UIViewAutoresizingFlexibleWidth        = 1 << 1,
    UIViewAutoresizingFlexibleRightMargin  = 1 << 2,
    UIViewAutoresizingFlexibleTopMargin    = 1 << 3,
    UIViewAutoresizingFlexibleHeight       = 1 << 4,
    UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};
typedef NSUInteger UIViewAutoresizing;
2个回答

3

我认为您在这里只有一件事情错了: NSUInteger 不是一个Objective-C对象,而是在32位系统上是一个 unsigned int,在64位系统上是一个 unsigned long。所以实际上正在发生的事情是:

typedef unsigned int UIViewAutoresizing;

或者

typedef unsigned long UIViewAutoresizing;

为了更多参考,我添加了这个:

#if __LP64__ || NS_BUILD_32_LIKE_64
typedef long NSInteger;
typedef unsigned long NSUInteger;
#else
typedef int NSInteger;
typedef unsigned int NSUInteger;
#endif

Source: CocoaDev


错误,应该相反。32位系统上是int,64位系统上是long - JustSid

3

问题在于这些旗标是用作位掩码的,这会导致枚举类型出现问题。例如,如果它看起来像这样:

typedef enum {
    UIViewAutoresizingNone                 = 0,
    UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,
    UIViewAutoresizingFlexibleWidth        = 1 << 1,
    UIViewAutoresizingFlexibleRightMargin  = 1 << 2,
    UIViewAutoresizingFlexibleTopMargin    = 1 << 3,
    UIViewAutoresizingFlexibleHeight       = 1 << 4,
    UIViewAutoresizingFlexibleBottomMargin = 1 << 5
} UIViewAutoresizing;

当你需要在一个视图上使用 UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight 的时候,你会调用 setAutoresizingMask: 方法。如果编译器出现警告,你必须将其显式地强制转换回 UIViewAutoresizing 类型。然而,NSUInteger 可以接受比特掩码。

除此之外,le2所说的关于 NSUInteger 不是ObjC对象的问题也是正确的。


所以匿名枚举只是声明常量值的符号名称(类似于#define),而typedef仅通过命名约定与枚举相关(UIViewAutoresizing___)?我认为这很有道理。 - Keith
@Keith:是的,没错。编译器强制传递正确类型到枚举在这些情况下并不是必要的,甚至是反直觉的。在需要时,苹果使用typedefed枚举。 - JustSid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接