为什么可可不到处使用相同的枚举声明风格?
我想知道可可上不同风格的枚举声明背后的基本原理是什么?
像这样:
enum { constants.. }; typedef NSUInteger sometype;
使用 typedef 使 NSUInteger 的分配无需强制转换即可工作的原因是什么?
有时 typedef 是 NSInteger/NSUInteger 之一,为什么不总是使用 NSInteger 呢?使用 NSUInteger 有真正的好处吗?
有时仍然使用枚举标记名,例如 此处位于 _NSByteOrder 上。
这个答案也非常有用:What is a typedef enum in Objective-C?。
I was wondering what is the rationale behind different styles of enum declaration on cocoa?
Like this:
enum { constants.. }; typedef NSUInteger sometype;
Is the reason to use typedef to get assigments to NSUInteger to work without casting?
Sometimes the typedef is either of NSInteger/NSUInteger, why not use NSInteger always? Is there real benefit using NSUInteger?
Enum tagnames are still used sometimes, like here on _NSByteOrder.
This answer was very useful too: What is a typedef enum in Objective-C?.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
typedef 用于指定枚举值的基本类型。您始终可以将枚举值转换为另一种类型,只要您通过转换为较小的类型(
NSUInteger
到unsigned Short
)来截断该值即可。NSInteger
和NSUInteger
的引入是为了通过为有符号和无符号整数提供架构/平台独立类型来简化应用程序的 64 位迁移。这样,无论CPU有多少位,应用程序都不需要重写。该选择取决于枚举中的值。有些枚举有很多值,因此它们需要所有可用的位:
我不知道苹果开发团队是否有这样的选择规则。我希望如此...
The typedef is used to specify the base type for the enumeration values. You can always cast a enumeration value to another type as long as you truncate the value, by casting to a smaller type (
NSUInteger
tounsigned short
).NSInteger
andNSUInteger
were introduced to ease the 64 bits migration of applications, by providing a architecture/platform independent type for both signed and unsigned integers. This way, no matter how many bits the CPU has, applications do no need to be rewritten.The choice depends on the values in the enumeration. Some enumerations have a lot of values, so they need all the bits available:
I don't know if there a rule of choice in Apple development's team for that. I hope so...
虽然您可以使用类似的东西,但
不能保证数据类型的最终位大小。嗯,这并不完全正确,但它足够真实。 API 最好以具体的数据大小来定义,而不是根据所使用的编译器设置进行更改。
Whilst you could use something like
there is no guarantee about the eventual bitsize of the datatype. Well, thats not strictly true, but its true enough. Its better for APIs to be defined in concrete data sizes, than with something that can change depending on the compiler settings being used.
几个原因:
原因 1:灵活性:
声明一个枚举。您可以在任何地方使用值
yes
、no
和maybe
并将它们分配给任何整数类型。您还可以将其用作类型,通过编写这使得它很好,因为如果一个函数采用 enum lickahoctor 类型的参数,您就会知道您可以分配
yes
,no 或
maybe
。此外,调试器会知道,因此它将显示符号名称而不是数值。问题是,编译器只允许您将enum lickahoctor
中定义的值分配给myVar
。例如,如果您想在基类中定义一些标志,然后在子类中添加更多标志,则不能这样做。如果你使用 int 代替,就不会有这个问题。所以你想使用某种 int,这样你就可以分配任意常量。
原因 2:二进制兼容性:
编译器会选择适合您在枚举中定义的所有常量的合适大小。无法保证您会得到什么。因此,如果您将包含此类变量的结构直接写入文件,则无法保证当您在应用程序的下一版本中读回它时它仍然具有相同的大小(根据 C 标准,至少 - - 实际情况并没有那么暗淡)。
如果您使用某种 int 代替,平台通常会保证该数字的特定大小。特别是如果您使用保证具有特定大小的类型之一,例如 int32_t/uint32_t。
原因 3:可读性和自文档化
当您在上面声明 myVar 时,您可以在其中放入哪些值立即显而易见。如果您只使用 int 或
uint32_t
,则不是。因此,您要做的就是在常量附近为整数定义一个好听的名称,以提醒人们这种类型的变量可以保存该值。但您仍然可以获得可预测的固定大小的好处,并且能够在需要时在子类中定义其他值。
原因 4:支持位域
枚举类型变量仅支持从其选项中指定一个值。因此,如果您尝试实现位字段,则无法将其键入为位字段。此外,您需要使用无符号变量来避免符号扩展搞砸您。
Several reasons:
Reason 1: Flexibility:
declares an enumeration. You can use the values
yes
,no
andmaybe
anywhere and assign them to any integral type. You can also use this as a type, by writingThis makes it nice because if a function takes a parameter with the type enum lickahoctor you'll know that you can assign
yes
,no
ormaybe
to it. Also, the debugger will know, so it'll display the symbolic name instead of the numerical value. Trouble is, the compiler will only let you assign values you've defined inenum lickahoctor
tomyVar
. If you for example want to define a few flags in the base class, then add a few more flags in the subclass, you can't do it this way.If you use an int instead, you don't have that problem. So you want to use some sort of int, so you can assign arbitrary constants.
Reason 2: Binary compatibility:
The compiler chooses a nice size that fits all the constants you've defined in an enum. There's no guarantee what you will get. So if you write a struct containing such a variable directly to a file, there is no guarantee that it will still be the same size when you read it back in with the next version of your app (according to the C standard, at least -- it's not quite that bleak in practice).
If you use some kind of int instead, the platform usually guarantees a particular size for that number. Especially if you use one of the types guaranteed to be a particular size, like
int32_t
/uint32_t
.Reason 3: Readability and self-documentation
When you declare myVar above, it's immediately obvious what values you can put in it. If you just use an int, or an
uint32_t
, it isn't. So what you do is you useto define a nice name for the integer somewhere near the constants that will remind people that a variable of this type can hold this value. But you still get the benefit of a predictable, fixed size and the ability to define additional values in subclasses, if needed.
Reason 4: Support for bitfields
enum-typed variables only support assigning exactly one value from their options. So if you're trying to implement a bit field, you can't type it as a bitfield. Furthermore, you need to use unsigned variables to avoid sign extension from screwing you over.