为什么可可不到处使用相同的枚举声明风格?

发布于 2024-08-21 08:52:42 字数 676 浏览 7 评论 0原文

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

像这样:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

铜锣湾横着走 2024-08-28 08:52:43

就是使用typedef来获取的原因
分配给 NSUInteger 来工作
没有铸造?

typedef 用于指定枚举值的基本类型。您始终可以将枚举值转换为另一种类型,只要您通过转换为较小的类型(NSUIntegerunsigned Short)来截断该值即可。

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

有时 typedef 是以下之一
NSInteger/NSUInteger,为什么不使用
NSInteger 总是?有没有真实的
使用 NSUInteger 有什么好处?

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

  • NSInteger 提供 2^31 个正值和负值(在 32 位架构上)。
  • NSUInteger 提供 2^32 个正值(在 32 位架构上)。
  • 如果枚举仅包含正值,则使用 NSUInteger。
  • 如果枚举要包含正值和负值,则使用 NSInteger。
  • NSUInteger 通常用于标志枚举,因为它提供了 32 个不同的值(在 32 位架构上)可以随意组合。

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

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

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 to unsigned short).

NSInteger and NSUInteger 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.

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

The choice depends on the values in the enumeration. Some enumerations have a lot of values, so they need all the bits available:

  • NSInteger offers 2^31 positive and negative values (on 32 bits architecture).
  • NSUInteger offers 2^32 positive values (on 32 bits architecture).
  • If you enumeration is meant to only contain positive values, then use NSUInteger.
  • If you enumeration is meant to contain both positive and negative values, then use NSInteger.
  • NSUInteger is usually used for flag enumeration, as it provides 32 distinct values (on 32 bits architecture) to be combined at will.

I don't know if there a rule of choice in Apple development's team for that. I hope so...

病女 2024-08-28 08:52:43

虽然您可以使用类似的东西,但

  typedef enum { constants... } sometype;

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

Whilst you could use something like

  typedef enum { constants... } sometype;

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.

心头的小情儿 2024-08-28 08:52:42

几个原因:

原因 1:灵活性:

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

声明一个枚举。您可以在任何地方使用值 yesnomaybe 并将它们分配给任何整数类型。您还可以将其用作类型,通过编写

enum lickahoctor myVar = yes;

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

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

原因 2:二进制兼容性:

编译器会选择适合您在枚举中定义的所有常量的合适大小。无法保证您会得到什么。因此,如果您将包含此类变量的结构直接写入文件,则无法保证当您在应用程序的下一版本中读回它时它仍然具有相同的大小(根据 C 标准,至少 - - 实际情况并没有那么暗淡)。

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

原因 3:可读性和自文档化

当您在上面声明 myVar 时,您可以在其中放入哪些值立即显而易见。如果您只使用 int 或 uint32_t,则不是。因此,您要做的就是

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

在常量附近为整数定义一个好听的名称,以提醒人们这种类型的变量可以保存该值。但您仍然可以获得可预测的固定大小的好处,并且能够在需要时在子类中定义其他值。

原因 4:支持位域

枚举类型变量仅支持从其选项中指定一个值。因此,如果您尝试实现位字段,则无法将其键入为位字段。此外,您需要使用无符号变量来避免符号扩展搞砸您。

Several reasons:

Reason 1: Flexibility:

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

declares an enumeration. You can use the values yes, no and maybe anywhere and assign them to any integral type. You can also use this as a type, by writing

enum lickahoctor myVar = yes;

This makes it nice because if a function takes a parameter with the type enum lickahoctor you'll know that you can assign yes, no or maybe 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 in enum lickahoctor to myVar. 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 use

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

to 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文