objective-c - 枚举值 : NSInteger or int?

标签 objective-c cocoa enums typedef nsinteger

tl;dr 版本

当这样声明一个枚举时,如何保证枚举常量的数据类型是 NSUInteger 而不是 unsigned int:

enum {
    NSNullCellType = 0,
    NSTextCellType = 1,
    NSImageCellType = 2
};
typedef NSUInteger NSCellType;

NSUInteger 的 typedef 似乎与枚举声明没有任何关联。

完整版

我正在阅读 Apple 的 64-Bit Transition Guide for Cocoa 有关枚举值的一些指导,我提出了一个问题。这是枚举常量部分的(冗长)引用,强调我的:

A problem with enumeration (enum) constants is that their data types are frequently indeterminate. In other words, enum constants are not predictably unsigned int. With conventionally constructed enumerations, the compiler actually sets the underlying type based on what it finds. The underlying type can be (signed) int or even long. Take the following example:

type enum {
    MyFlagError = -1,
    MyFlagLow = 0,
    MyFlagMiddle = 1,
    MyFlagHigh = 2
} MyFlagType;

The compiler looks at this declaration and, finding a negative value assigned to one of the member constants, declares the underlying type of the enumeration int. If the range of values for the members does not fit into an int or unsigned int, then the base type silently becomes 64-bit (long). The base type of quantities defined as enumerations can thus change silently size to accord with the values in the enumeration. This can happen whether you're compiling 32-bit or 64-bit. Needless to say, this situation presents obstacles for binary compatibility.

As a remedy for this problem, Apple has decided to be more explicit about the enumeration type in the Cocoa API. Instead of declaring arguments in terms of the enumeration, the header files now separately declare a type for the enumeration whose size can be specified. The members of the enumeration and their values are declared and assigned as before. For example, instead of this:

typedef enum {
    NSNullCellType = 0,
    NSTextCellType = 1,
    NSImageCellType = 2
} NSCellType;

there is now this:

enum {
    NSNullCellType = 0,
    NSTextCellType = 1,
    NSImageCellType = 2
};
typedef NSUInteger NSCellType;

The enumeration type is defined in terms of NSInteger or NSUInteger to make the base enumeration type 64-bit capable on 64-bit architectures.

我的问题是:鉴于 typedef 似乎没有明确地与枚举声明绑定(bind),如何知道它们的数据类型是 unsigned int 还是 NSUInteger?

最佳答案

现在有 NS_ENUM 开始 Xcode 4.5:

typedef NS_ENUM(NSUInteger, NSCellType) {
    NSNullCellType = 0,
    NSTextCellType = 1,
    NSImageCellType = 2
};

如果你使用二进制标志,你可以考虑 NS_OPTIONS:

typedef NS_OPTIONS(NSUInteger, MyCellFlag) {
    MyTextCellFlag = 1 << 0,
    MyImageCellFlag = 1 << 1,
};

关于objective-c - 枚举值 : NSInteger or int?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8496903/

相关文章:

swift - 在 swift 4.2 中从公共(public)枚举访问内部枚举时出错

ios - UIImageView 内容模式不起作用

objective-c - CG图像引用 |内存消耗|泄露

objective-c - Xcode 10 不索引新创建的类

ios - 在ios中获取视频的FPS

objective-c - 如何以编程方式关闭窗口的 NSAlert 运行模式

MacOS GameKit 排行榜无法加载,并出现 App "does not support leaderboards"错误

javascript - 如何使用实现接口(interface)制作 Typescript 枚举

iOS : Fail to use Global object class - Singleton

c# - 如何向枚举添加扩展方法