使用self.amiteLbl!
是明確聲明此時self.amiteLbl
裏一定有值,無論什麼情況都調用後面的.text賦值方法。
而使用self.view?
是聲明此時並不確定self.view裏是否有值,所以只在view有值時調用後面.addSubview
方法。
這樣做的目的一是讓代碼更明確, 二是給編譯器提供更多線索,在編譯時發現更多潛在錯誤。
聲明爲Optional只需要在類型後面緊跟一個?
即可。如:
var strValue: String? //?相當於下面這種寫法的語法糖
var strValue: Optional<String>
上面這個Optional的聲明,意思不是”我聲明瞭一個Optional的String值”, 而是”我聲明瞭一個Optional類型值,它可能包含一個String值,也可能什麼都不包含”,也就是說實際上我們聲明的是Optional類型,而不是聲明瞭一個String類型,這一點需要銘記在心。
然後怎麼使用Optional值呢?文檔中也有提到說,在使用Optional值的時候需要在具體的操作,比如調用方法、屬性、下標索引等前面需要加上一個?
,如果是nil值,也就是Optional.None
,會跳過後面的操作不執行,如果有值,就是Optional.Some
,可能就會拆包(unwrap),然後對拆包後的值執行後面的操作,來保證執行這個操作的安全性,比如:
let hashValue = strValue?.hashValue
strValue是Optional的字符串,如果strValue是nil,則hashValue也爲nil,如果strValue不爲nil,hashValue就是strValue字符串的哈希值(其實也是用Optional wrap後的值)
另外,?還可以用在安全地調用protocol類型方法上,比如:
@objc protocol Downloadable {
@optional func download(toPath: String) -> Bool;
}
@objc class Content: Downloadable {
//download method not be implemented
}
var delegate: Downloadable = Downloadable()
delegate.download?("some path")
因爲上面的delegate是Downloadable類型的,它的download
方法是optional,所以它的具體實現有沒有download
方法是不確定的。Swift提供了一種在參數括號前加上一個?
的方式來安全地調用protocol的optional方法。
另外如果你需要像下面這樣向下轉型(Downcast),可能會用到 as?
:
if let dataSource = object as? UITableViewDataSource {
let rowsInFirstSection = dataSource.tableView(tableView, numberOfRowsInSection: 0)
}
到這裏我們看到了
?
的幾種使用場景:1.聲明Optional值變量
2.用在對Optional值操作中,用來判斷是否能響應後面的操作
3.用於安全調用protocol的optional方法
4.使用 as? 向下轉型(Downcast)
直接上例子,strValue是Optional的String:
let hashValue = strValue!.hashValue
這裏的
!
表示“我確定這裏的的strValue一定是非nil的,盡情調用吧” ,比如這種情況:
if strValue {
let hashValue = strValue!.hashValue
}
考慮下這一種情況,我們有一個自定義的
MyViewController
類,類中有一個屬性是myLabel
,myLabel是在viewDidLoad中進行初始化。因爲是在viewDidLoad中初始化,所以不能直接聲明爲普通值:var myLabel : UILabel
,因爲非Optional的變量必須在聲明時或者構造器中進行初始化,但我們是想在viewDidLoad中初始化,所以就只能聲明爲Optional:var myLabel:
UILabel?
, 雖然我們確定在viewDidLoad中會初始化,並且在ViewController的生命週期內不會置爲nil,但是在對myLabel操作時,每次依然要加上!
來強制拆包(在讀取值的時候,也可以用?
,謝謝iPresent在回覆中提醒),比如:
myLabel!.text = "text"
myLabel!.frame = CGRectMake(0, 0, 10, 10)
...
對於這種類型的值,我們可以直接這麼聲明:var myLabel: UILabel!
, 果然是高(hao)大(gui)上(yi)的語法!, 這種是特殊的Optional,稱爲Implicitly Unwrapped Optionals
, 直譯就是隱式拆包的Optional,就等於說你每次對這種類型的值操作時,都會自動在操作前補上一個!
進行拆包,然後在執行後面的操作,當然如果該值是nil,也一樣會報錯crash掉。
var myLabel: UILabel! //!相當於下面這種寫法的語法糖
var myLabel: ImplicitlyUnwrappedOptional<UILabel>
那麼
!
大概也有兩種使用場景1.強制對Optional值進行拆包(unwrap)
2.聲明Implicitly Unwrapped Optionals
值,一般用於類中的屬性
http://joeyio.com/ios/2014/06/04/swift---/