关于C#:为什么cocoa到处都没有使用相同的枚举声明样式?

Why doesn't cocoa use the same enum declaration style everywhere?

我想知道的是在对不同类型of is the enum在线申报可可?P></

这样:P></

1
enum { constants.. }; typedef NSUInteger sometype;

使用typedef is the reason to to get to nsuinteger铸造作业的工作没有?P></

有时nsinteger typedef is of the nsuinteger /或者nsinteger总是使用,为什么不呢?there is using real nsuinteger福利?P></

有时我tagnames are used枚举类,_ nsbyteorder在线这里。P></

这是非常有用的?答案是:typedef enum太在Objective-C中?。P></


几个原因:

原因1:灵活性:

1
enum lickahoctor { yes = 0, no = 1, maybe = 2 };

声明枚举。您可以在任何地方使用值yesnomaybe,并将它们赋给任何整型。您还可以通过编写

1
enum lickahoctor myVar = yes;

这样做很好,因为如果函数接受类型为enum lickahoctor的参数,您将知道可以将yesnomaybe分配给它。另外,调试器会知道,因此它将显示符号名而不是数值。问题是,编译器只允许您将在enum lickahoctor中定义的值分配给myVar。例如,如果您想在基类中定义一些标志,然后在子类中添加更多的标志,则不能这样做。

如果你用一个int代替,你就不会有这个问题。所以你想使用某种类型的int,这样你就可以分配任意的常量。

原因2:二进制兼容性:

编译器会选择一个适合您在枚举中定义的所有常量的合适大小。不能保证你会得到什么。因此,如果你直接将一个包含这样一个变量的结构写到一个文件中,当你把它和下一个版本的应用程序一起读回来时,它仍然是相同的大小(根据C标准,至少在实践中它并没有那么黯淡)。

如果您使用某种类型的int,平台通常保证该数字具有特定的大小。特别是如果您使用的类型保证是一个特定的大小,如int32_t/uint32_t

原因3:可读性和自文档

当您在上面声明myvar时,很明显您可以将哪些值放入其中。如果你只是使用int或uint32_t,它不是。所以你所做的就是使用

1
2
enum { yes, no, maybe };
typedef uint32_t lickahoctor;

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

原因4:支持位域

枚举类型的变量只支持从其选项中分配一个值。因此,如果您试图实现位字段,则不能将其作为位字段键入。此外,您需要使用无符号变量来避免符号扩展把您搞砸。


Is the reason to use typedef to get
assigments to NSUInteger to work
without casting?

typedef用于指定枚举值的基类型。只要截断一个枚举值,就可以将该枚举值强制转换为另一个类型(NSUInteger强制转换为unsigned short)。

引入NSIntegerNSUInteger,通过为有符号整数和无符号整数提供独立于体系结构/平台的类型,简化应用程序的64位迁移。这样,不管CPU有多少位,应用程序都不需要重写。

Sometimes the typedef is either of
NSInteger/NSUInteger, why not use
NSInteger always? Is there real
benefit using NSUInteger?

选择取决于枚举中的值。有些枚举有很多值,因此它们需要所有可用的位:

  • nsinteger提供2^31正值和负值(在32位体系结构上)。
  • nsinteger提供2^32正值(在32位体系结构上)。
  • 如果枚举只包含正值,则使用nsinteger。
  • 如果枚举要同时包含正值和负值,请使用nsinteger。
  • NSUInteger通常用于标记枚举,因为它提供32个不同的值(在32位体系结构上),可以任意组合。

我不知道苹果开发团队是否有选择的规则。我希望如此…


同时你可以使用

1
  typedef enum { constants... } sometype;

无法保证数据类型的最终位大小。嗯,这不是严格意义上的事实,但它是足够真实的。对于API来说,用具体的数据大小来定义比用一些可以根据所使用的编译器设置而改变的东西更好。