[翻译]Swift Optionals:何时使用'!'和'?' ?

本文由NikoXu (iOS 爱好者) 翻译

Swift Optionals:什么是Optional ?
Swift Optionals:何时使用'!'和'?' ?
Swift Optionals:何时使用'if-let' ?
Swift Optionals:何时使用'as?'和'as' ?

何时使用 ?和 !

让我们假设你有一个基于UIKit写的iPhone 应用。现在你想在view controller使用一些代码,使之能在屏幕里的view controller上出场一个新的view controller。你打算通过navigation controller 来 push这个新的view controller到屏幕上。

正如你所知道的,每个ViewController实例有一个navigationController的属性。如果你想制作一个基于navigation controller的应用,这个属性将在你的应用里被自动创建,而你可以用navigation控制器来push或者pop你所需要的view controllers。如果你使用了single app project的模板,Xcode不会自动为你自动创建navigation controller,因此你的应用的默认view controller不会创建** navigationController**的属性。

我想你已经想到这个场景很适合使用Optional数据类型。如果你查看UIViewController的文档你会发现navigationController 是这样被定义在库里面的:

var navigationController: UINavigationController? { get }

那么让我们回到我们使用场景。如果你能肯定你的view controller总是拥有一个 navigation controller,那么你就可以对它直接强行解包(force unwrap):

controller.navigationController!.pushViewController(myViewController, animated: true)

当你在属性名称之后标记上' ! ',那么就相当于告诉编译器“我不在乎这个属性是optional的,我知道这块代码在执行的整个过程中都是有值的状态,把这个optional类型当作普通的数据类型对待就行”。这样做好吗?而当你的view controller 不存在这样一个navigation controller的时候会发生什么呢?还是将一个错误的值一直被存储在navigation controller里?你看到的结果将是你的应用会崩溃掉,正如你的代码一样不完善和难看。

因此,使用 '!' 仅仅适合你101%确定这样做是安全的。

那么当我们不能确定这个属性是一个navigation controller对象该如何做呢?这时你可以使用 '?' 取代 '!' :

controller.navigationController?.pushViewController(myViewController, animated: true)

在属性名称后面添加的'?'便是告诉编译器这个属性是否为nil,那么:当它不为nil的时候使用它,否则就把它当做一个真正的nil对象。'?'符号让你更加高效灵活的使用navigation controller。而不需要检查类型或者在类型之间做转换。当你不知道是否是一个navigation controller对象却希望只有当它是一个navigation controller对象用它做点什么的情况下,这样的语法是非常完善且实用的。

了解更多'!'和'?'使用技巧请阅读可选链式调用 Optional Chaining

这样真的很棒!但是如果你希望在它不是一个navigation controller对象的情况下做点什么的时候该怎么做呢?比如此时显示一个给用户解释情况的警示窗口。

这时你需要使用的是if-let语法。

如何使用Optionals请阅读##

Swift Optionals:什么是Optional ?
Swift Optionals:何时使用'!'和'?' ?
Swift Optionals:何时使用'if-let' ?
Swift Optionals:何时使用'as?'和'as' ?

翻译菌: 因为是分次翻译的,所以把原文分成4个较小的篇幅来翻译的。在学习Swift的路途上,如有不妥,望指正。

你可能感兴趣的:([翻译]Swift Optionals:何时使用'!'和'?' ?)