【发布时间】:2019-06-16 12:44:49
【问题描述】:
在 Swift 中,init(rawValue:) 系统确保将 Int 强制转换为枚举要么导致有效的枚举大小写,要么导致 nil。
在 Objective-C 中没有这样的安全性,可以通过强制转换非成员“rawValue”来创建无效的枚举成员。
typedef NS_ENUM(NSInteger, ExampleEnum) {
first = 0,
second,
third,
};
+ (NSString *)stringForCase:(ExampleEnum)enumCase {
switch (enumCase) {
case first: return @"first";
case second: return @"second";
case third: return @"third";
}
}
+ (void)testEnum {
ExampleEnum invalidCase = (ExampleEnum)3; // this "rawValue" is out of bounds
NSString *string = [self stringForCase:invalidCase]; // nil
}
打开枚举时,如果未处理枚举情况,编译器会警告您:
枚举值“第三个”未在开关中处理
但是一旦处理了所有情况,就没有类似的警告表明枚举的无效成员仍然可能出现“默认”情况。
在这种情况下的行为是什么? NSString 方法似乎返回nil,并且没有观察到崩溃。但是该方法没有return。 return nil是自动生成的吗,在什么情况下?
请注意,“详尽”开关之后的代码语句不会导致通常会生成警告:
代码永远不会被执行
【问题讨论】:
-
切向,但您可能对这篇博文感兴趣(快速阅读):owensd.io/2014/10/09/building-swift-style-enums-in-objc-part-3
-
"但是如果出现一些 hack 并在我漂亮的函数中抛出一个未初始化的 int 怎么办?" - softwareengineering.stackexchange.com/questions/179269/…
-
旁白:FWIW,在考虑 C(或 ObjC)中的枚举时,与大量其他语言中的枚举不同,它们在概念上并不是真正的“特殊”类型——认为枚举只是整数的语法糖 some 有用的编译器警告围绕它们的使用,但还有其他陷阱。对不在定义的枚举集中的值使用一些随机整数并不是“无效”,因为它只是编写(或设计)错误的代码。由于这种设置,枚举在 C 中是一种痛苦,而且几乎所有后来的语言(包括 Swift)都使枚举更加一流和有用。
标签: c objective-c enums switch-statement