【发布时间】:2011-11-17 07:15:39
【问题描述】:
有什么区别
typedef enum {
...
} Name;
和
enum {
...
};
typedef NSUInteger Name;
?如果功能相同,那么第二种形式有什么用?这不是不必要的混乱吗?
【问题讨论】:
-
第二个从 NSUInteger 派生一个类型,而不是第一个。
标签: objective-c ios enums
有什么区别
typedef enum {
...
} Name;
和
enum {
...
};
typedef NSUInteger Name;
?如果功能相同,那么第二种形式有什么用?这不是不必要的混乱吗?
【问题讨论】:
标签: objective-c ios enums
前者定义了一个类型名来引用一个枚举。这是 C 中大多数枚举的命名方式。尽管后者有点不同,它在 Cocoa 框架中很普遍。使用后者有两个原因。第一个是如果您的枚举定义了一个位域,并且您希望在此处使用它,因为当您提供“名称”值时,您将提供枚举值的组合。换句话说,如果你说类似
[self doSomethingWithBitfield:(Enum1 | Enum2)]
您传递的不是 Name 值,而是一个整数,它是两者的组合。
然而,Cocoa 框架甚至对非位域值也使用这种习惯用法,这是有充分理由的:API 稳定性。根据 C 标准,枚举的底层整数类型需要能够包含枚举中的所有值,但编译器会另外选择。这意味着添加一个新的枚举值可能会改变枚举的整数类型(例如,添加 -1 可以使其有符号,添加 60 亿可以使其成为 long long 等)。从 API 稳定性的角度来看,这是一件坏事,因为采用此枚举值的方法的类型编码可能会意外更改,并可能破坏现有代码和二进制文件。为了防止这种情况发生,Cocoa 框架通常将类型定义为 NSUInteger(如果需要负数,则为 NSInteger),因此 API 和类型编码保持稳定。
【讨论】:
enum 与C 一样古老,因此是Objective-C 的一部分。
它只是int 类型的显式编码。它对于调试非常有用,大多数较新的编译器都可以基于它进行优化。 (你应该完全忽略)。它最有助于使您的代码更具可读性(对其他人,或在您睡觉后对您自己)。
typedef enum {
...
} NameType ;
后面是
NameType name;
这通常是 typedef 的首选样式,
您的第二个示例将不将 typedef 绑定到您要指定的值,该值应仅属于给定类型。
请注意,这不会阻止您执行
name = 10244; // some non-valid value not listed in the enumeration
但某些编译器在这种情况下可能会生成警告,
我今天遇到了 Apple 对以下内容的使用:
enum {
NSFetchedResultsChangeInsert = 1,
NSFetchedResultsChangeDelete = 2,
NSFetchedResultsChangeMove = 3,
NSFetchedResultsChangeUpdate = 4
};
typedef NSUInteger NSFetchedResultsChangeType;
他们这样做是因为他们真的希望NSFetchedResultsChangeType 是他们定义为NSUInteger 的类型。这个可以是int,但也可以是别的东西。对于 1、2、3 和 4 的值,我们 与类型无关。但他们正在编码到不同的抽象级别,因为他们是工具提供者。
您永远不应该向 Apple 寻求编码风格提示。如果您看到一些看起来像是更清洁/更好的编码方式的东西,通常是这样。正如 Kevin 所说,API 稳定性对他们来说至关重要。
编辑(2013 年 1 月) 如果您有权访问 WWDC 2012 会议视频,您应该观看 Session 405 - Modern Objective-C 6:00-10:00。在较新的编译器中讨论了一种新语法,该语法允许显式调整类型大小并将值与类型紧密结合。 (借用自 C++ 11)
enum NSFetchedResultsChangeType : NSUInteger {
NSFetchedResultsChangeInsert = 1,
NSFetchedResultsChangeDelete = 2,
NSFetchedResultsChangeMove = 3,
NSFetchedResultsChangeUpdate = 4
};
【讨论】:
enum CustomButtonEvent : UIControlEvents { CustomValue = UIControlEventApplicationReserved };。我还添加了typedef enum CustomButtonEvent CustomButtonEvent 以避免每次都输入“枚举”。
enum 类型而在自定义枚举类型之前没有写 enum 时出现)在使用 typedef 枚举时消失,就像苹果在其视频中使用它一样: typedef enum NSNumberFormatterStyle : NSUInteger {...} NSNumberFormatterStyle;@bshirley 您介意更改您对该代码的答案吗?