为什么Cocoa在不同地方使用不同的枚举声明风格?
为什么Cocoa在不同地方使用不同的枚举声明风格?
我正在思考关于cocoa不同枚举声明样式的理由是什么?像这样:
enum { constants.. }; typedef NSUInteger sometype;
使用typedef的原因是为了在不用强制类型转换的情况下使NSUInteger分配工作吗?
有时typedef使用的是NSInteger / NSUInteger,为什么不总是使用NSInteger?使用NSUInteger是否有真正的好处?
枚举标记有时仍在使用,比如_NsByteOrder上的这里。
这个答案也很有用:Objective-C中的typedef枚举是什么?。
使用typedef的原因是为了让NSUInteger的赋值可以正常工作而无需进行转换吗?
typedef用于指定枚举值的基础类型。只要将值截断,通过将其转换为较小的类型(NSUInteger
到 unsigned short
),你就可以将枚举值强制转换成另一种类型。
NSInteger
和 NSUInteger
被引入是为了简化应用程序的64位迁移,提供一个独立于架构/平台的有符号和无符号整数类型。这样,无论CPU有多少位,应用程序都不需要被重新编写。
有时typedef是NSInteger/NSUInteger中的任一个,为什么不总是使用NSInteger?使用NSUInteger有真正的好处吗?
选择取决于枚举中的值。有些枚举有很多值,所以需要所有可用的位:
- 在32位架构上,NSInteger提供了2^31个正和负的值。
- 在32位架构上,NSUInteger提供了2^32个正值。
- 如果您的枚举只包含正值,请使用NSUInteger。
- 如果您的枚举包含正和负值,请使用NSInteger。
- NSUInteger通常用于标志枚举,因为它提供了32个不同的值(在32位架构上)可以任意组合。
我不知道在苹果开发团队中是否有一个选择规则。希望是这样的。
有几个原因:
原因 1:灵活性:
enum lickahoctor { yes = 0, no = 1, maybe = 2 };
声明了一个枚举。您可以在任何地方使用值yes
、no
和maybe
,并将它们分配给任何整数类型。您还可以将此作为类型使用,通过编写
enum lickahoctor myVar = yes;
这很好,因为如果一个函数接受类型为枚举lickahoctor的参数,那么您将知道您可以将yes
、no
或maybe
分配给它。此外,调试器会知道,因此它会显示符号名称而不是数字值。问题是,编译器只会让您将在enum lickahoctor
中定义的值分配给myVar
。例如,如果您想在基类中定义一些标志,然后在子类中添加一些标志,您无法通过这种方式实现。
如果使用int,就不会有这个问题。因此,您需要使用某种int,以便可以分配任意常量。
原因 2:二进制兼容性:
编译器选择一个漂亮的大小,适合您在枚举中定义的所有常量。没有保证您会得到什么样的大小。因此,如果您将包含此类变量的结构直接写入文件,则无法保证在使用您的应用程序的下一个版本时,它仍将是相同的大小(至少根据C标准如此-在实践中不是完全那么bleak)。
如果使用某种int,通常平台会保证该数字具有特定的大小。尤其是如果使用了保证具有特定大小的类型之一,例如int32_t
/uint32_t
。
原因 3:易读性和自我说明性
当您上面声明myVar时,可以立即明确可以放入其中的值。如果只使用int或uint32_t
,则不是这样。因此,您使用
enum { yes, no, maybe }; typedef uint32_t lickahoctor;
在靠近常量的地方定义一个漂亮的名称,以提醒人们此类型的变量可以容纳此值。但是,如果需要,您仍然可以获得预测性的固定大小和定义子类中的其他值的能力。
原因 4:位域支持
枚举类型的变量仅支持从其选项中分配一个值。因此,如果您正在尝试实现位字段,则无法将其类型设置为位字段。此外,您需要使用无符号变量以避免符号扩展使您失败。