Swift编程语言书没有讨论这个,但是在Swift中所有对象变量都应该是可选的吗?因为从技术上讲,对象创建可能会失败并返回nil
(如Objective-C的情况)。那么,Swift for Swift类中的所有对象变量(或者至少是所有的Foundation类)都应声明为可选的吗?
let obj:NSData? = NSData()
答案 0 :(得分:5)
这可能是基于意见的,但我认为通常你希望变量是非可选的。
没有多少对象初始值设定项可以实际返回nil
。
在Obj-C中,您不会检查所有初始化程序是否都返回nil
。
NSArray *array = [[NSArray alloc] init];
if (array != nil) { //would you test this?
}
以同样的方式,不要让所有对象变量在Swift中都是可选的。只有您确实想要检查nil
值的那些。
顺便说一句,在纯Swift中,Object初始值设定项不能返回nil
,因为它们实际上没有返回值。在Swift中,对象初始化不会失败,所以我们在这里只讨论Obj-C的互操作性。
回答评论的一个例子:
NSData *data = [[NSData alloc] initWithContentsOfFile:@"some_file"];
在Swift中:
var data = NSData(contentsOfFile: "some_file")
如果文件不存在,我们会在两种语言中获得nil
。在Swift中,我们有一个隐式解包的可选项,因此赋值本身不会失败,如果需要,我们仍然可以测试nil
。
如果我们预期data
可能是nil
,那么两种语言的行为都是相同的,我们会以某种方式解决问题。如果我们没有预料到它,那就是一个bug,因为其他一切都是未定义的行为。
在Swift中,应用程序会提前崩溃 - 第一次尝试使用data
时。
在Obj-C中,结果将是绝对随机的 - 请注意,我们从未期望data
为nil
,因此我们的下一个陈述可能是:
[array addObject:data];
使应用程序崩溃。
然而,由于Obj-C的性质,在bug实际显露之前可能会发生数千条语句,并且它可以非常奇怪地显示出来 - 例如:数据解析可能失败,UI布局将失败,因为项目将丢失当我们期待他们等等。我们也可能会遇到一个迟到的崩溃。然而,自nil
返回以来,应用程序行为将是未定义的,因为我们没有考虑到这种可能性:
......事情可能无法执行,但它肯定不会使程序崩溃或使事情处于不稳定的状态......
评论中的两个陈述都是错误的。
错误的后期表现是调试Obj-C应用程序时最大的问题之一,使它们不安全。有时它们不会崩溃,但这并不意味着它们正常工作。 Swift考虑并提前崩溃是一个更好的替代方案,而不是隐藏的nil
对象在应用程序中传播自己并在几小时后崩溃应用程序。