为什么cocoa到处都没有使用相同的枚举声明风格?

Sim*_*nen 12 cocoa objective-c nsinteger nsuinteger

我想知道可可的不同风格的枚举声明背后的理由是什么?

像这样:

enum { constants.. }; typedef NSUInteger sometype;
Run Code Online (Sandbox Code Playgroud)

是否有理由使用typedef来获取NSUInteger的分配而不进行强制转换?

有时typedef是NSInteger/NSUInteger,为什么不总是使用NSInteger?使用NSUInteger真的有好处吗?

枚举标记名有时仍然使用,就像这里的_NSByteOrder.

这个答案也非常有用:Objective-C中的typedef枚举是什么?.

uli*_*ess 12

几个原因:

原因1:灵活性:

enum lickahoctor { yes = 0, no = 1, maybe = 2 };
Run Code Online (Sandbox Code Playgroud)

声明一个枚举.您可以在任何地方使用这些值yes,no并将maybe它们分配给任何整数类型.您也可以通过写作将其用作类型

enum lickahoctor myVar = yes;
Run Code Online (Sandbox Code Playgroud)

这使得它很好,因为如果一个函数将一个类型枚举lickahoctor你就会知道,你可以指定一个参数yes,nomaybe给它.此外,调试器将知道,因此它将显示符号名称而不是数值.麻烦的是,编译器只会让你指定你在定义的值enum lickahoctormyVar.例如,如果您想在基类中定义一些标志,那么在子类中添加一些标志,就不能这样做.

如果您使用int,则不会出现此问题.所以你想使用某种int,所以你可以分配任意常量.

原因2:二进制兼容性:

编译器选择一个适合你在枚举中定义的所有常量的大小.无法保证你会得到什么.因此,如果您将包含此类变量的结构直接写入文件,则无法保证在您使用下一版本的应用程序将其重新读入时它仍然具有相同的大小(根据C标准,至少 - - 在实践中并不是那么黯淡.

如果您使用某种类型的int,平台通常会保证该数字的特定大小.特别是如果你使用其中一种保证特定尺寸的类型,比如int32_t/ uint32_t.

原因3:可读性和自我记录

当您在上面声明myVar时,您可以立即明白其中的值.如果你只是使用int,或者a uint32_t,则不是.所以你做的就是用

enum { yes, no, maybe };
typedef uint32_t lickahoctor;
Run Code Online (Sandbox Code Playgroud)

为常量附近的整数定义一个很好的名称,它会提醒人们这种类型的变量可以保存这个值.但是,如果需要,您仍然可以获得可预测的固定大小以及在子类中定义其他值的能力.

原因4:支持位域

枚举变量仅支持从其选项中精确分配一个值.因此,如果您尝试实现位字段,则无法将其键入为位域.此外,您需要使用无符号变量来避免符号扩展使您无法使用.

  • "lickahoctor"为+1,尽管这是一个内心的笑话. (2认同)

小智 1

虽然你可以使用类似的东西

  typedef enum { constants... } sometype;
Run Code Online (Sandbox Code Playgroud)

无法保证数据类型的最终位大小。嗯,这并不完全正确,但它足够真实。API 最好以具体的数据大小来定义,而不是根据所使用的编译器设置进行更改。