Swift Programming Language 书没有讨论这个问题,但在 Swift 中所有对象变量都应该是可选的吗?因为从技术上讲,对象创建可能会失败并返回 nil
(就像 Objective-C 的情况一样)。那么 Swift 中所有用于 Swift 类(或至少所有 Foundation 类)的对象变量都应该声明为可选的吗?
let obj:NSData? = NSData()
最佳答案
这可能是基于意见,但我认为通常您希望变量是非可选的。
实际上可以返回 nil
的对象初始值设定项并不多。
在 Obj-C 中,您不会检查是否所有初始化器都返回 nil
。
NSArray *array = [[NSArray alloc] init];
if (array != nil) { //would you test this?
}
同理,不要让所有的对象变量在 Swift 中都是可选的。仅在您实际想要检查 nil
值时才使用。
顺便说一句,在纯 Swift 中,对象初始值设定项不能返回 nil
,因为它们实际上没有返回值。在 Swift 中,对象初始化不会失败,所以我们这里只讨论 Obj-C 互操作性。
一个回答评论的例子:
NSData *data = [[NSData alloc] initWithContentsOfFile:@"some_file"];
在 Swift 中:
var data = NSData(contentsOfFile: "some_file")
如果文件不存在,在两种语言中我们都会得到一个nil
。在 Swift 中,我们有一个隐式展开的可选值,因此赋值本身不会失败,如果我们愿意,我们仍然可以测试 nil
。
如果我们期望 data
可以是 nil
,那么两种语言的行为是相同的,我们就会以某种方式解决问题。如果我们没有预料到它,那就是一个错误,因为其他一切都是未定义的行为。
在 Swift 中,应用程序会提前崩溃 - 当您第一次尝试使用 data
时。
在 Obj-C 中,结果将是绝对随机的 - 请注意,我们从未期望 data
为 nil
,因此我们的下一个语句可能是:
[array addObject:data];
使应用程序崩溃。
但是,由于 Obj-C 的性质,在 bug 真正暴露自己之前可能会发生数千个语句,并且它可能会非常奇怪地暴露自己 - 例如:数据解析可能失败,UI 布局将失败,因为项目将丢失当我们期待他们时等等。我们也可能会遇到迟到的崩溃。然而,由于我们没有考虑到这种可能性,因此自 nil
返回以来,应用程序行为将是未定义的:
...things may not be executed, but it certainly won't crash the program or leave things in an unstable state...
评论中的两个陈述都是错误的。
错误的后期表现是调试 Obj-C 应用程序时最大的问题之一,使它们变得不安全。有时它们不会崩溃,但这并不意味着它们工作正常。 Swift 认为早期崩溃是比隐藏的 nil
对象在应用程序中传播自身并在数小时后崩溃应用程序更好的选择。
关于swift - 在 Swift 中,所有对象变量都应该是可选的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24231637/