在Swift中,所有对象变量都应该是可选的吗?

Boo*_*oon 6 swift

Swift编程语言书不讨论这个,但是在Swift中所有对象变量都应该是可选的吗?因为从技术上讲,对象创建可能会失败并返回nil(如Objective-C的情况).那么Swift for Swift类中的所有对象变量(或者至少对于所有的Foundation类)都应声明为可选的吗?

let obj:NSData? = NSData()
Run Code Online (Sandbox Code Playgroud)

Sul*_*han 5

这可能是基于意见的,但我认为通常你想要变量是非可选的.没有很多对象初始化器可以实际返回一个nil.

在Obj-C中,您不会检查是否所有初始化程序都返回nil.

NSArray *array = [[NSArray alloc] init];

if (array != nil) {  //would you test this?
}
Run Code Online (Sandbox Code Playgroud)

同样,不要让所有对象变量在Swift中都是可选的.只有你真正想要检查nil值的那些.

顺便说一句,在纯Swift中,Object初始值设定项不能返回a,nil因为它们实际上没有返回值.在Swift中,对象初始化不会失败,所以我们在这里只讨论Obj-C的互操作性.

回答评论的一个例子:

NSData *data = [[NSData alloc] initWithContentsOfFile:@"some_file"];
Run Code Online (Sandbox Code Playgroud)

在斯威夫特:

var data = NSData(contentsOfFile: "some_file")
Run Code Online (Sandbox Code Playgroud)

如果该文件不存在,我们会在两种语言中获得nil.在Swift中,我们有一个隐式解包的可选项,因此赋值本身不会失败,我们仍然可以测试nil是否需要.

如果我们预期data可能nil,两种语言的行为都是相同的,我们会以某种方式解决问题.如果我们没有预料到它,那就是一个bug,因为其他一切都是未定义的行为.

在Swift中,应用程序将在您第一次尝试使用时提前崩溃data.在Obj-C中,结果将是绝对随机的 - 请注意我们从未期望datanil,所以我们的下一个陈述可能是:

[array addObject:data];
Run Code Online (Sandbox Code Playgroud)

崩溃的应用程序.

但是,由于Obj-C的性质,在bug实际显露之前可能会发生数千条语句,并且它可以非常奇怪地显示出来 - 例如:数据解析可能会失败,UI布局将失败,因为我们预期时项目将丢失他们等等.我们也可能会遇到一个迟到的崩溃.然而,自nil返回以来,应用程序行为将是未定义的,因为我们没有考虑到这种可能性:

......事情可能无法执行,但它肯定不会使程序崩溃或使事情处于不稳定状态......

评论中的两个陈述都是错误的.

错误的后期表现是调试Obj-C应用程序时最大的问题之一,使它们不安全.有时它们不会崩溃,但这并不意味着它们正常工作.Swift认为并且早期崩溃是一个更好的选择,而不是隐藏的nil对象通过应用程序传播自己并在几小时后崩溃应用程序.