一、前言
Swift相較于OC是一門(mén)類(lèi)型更加安全的語(yǔ)言,其中引入的Optional類(lèi)型便是為了增強(qiáng)取值可靠性的一種方式。然而在新舊語(yǔ)言的轉(zhuǎn)換過(guò)程中總是會(huì)踩到坑中,由于自己對(duì)于這個(gè)概念的理解還沒(méi)有到位,在最近一次的實(shí)踐中就遇到了由于Optional Binding引發(fā)的問(wèn)題。
二、問(wèn)題場(chǎng)景
textFiled中的text屬性是一個(gè)可選(optional)類(lèi)型,在對(duì)輸入狀態(tài)進(jìn)行處理的時(shí)候肯定會(huì)涉及到對(duì)輸入內(nèi)容的邏輯操作。在OC中這種操作還是很直接的,直接使用.語(yǔ)法(textField.text)獲取屬性進(jìn)行判斷。
但在swift中text是一個(gè)可選屬性,直接對(duì)屬性進(jìn)行操作就比較冗余了。因此我們往往會(huì)寫(xiě)出如下的代碼。
if var text = textField.text {
/// 邏輯操作
}
這是swift中推薦的可選綁定的寫(xiě)法,在其中的邏輯操作中text就是textField.text解包出的值,因此可以通過(guò)判斷text的狀態(tài),獲知textField.text的狀態(tài)。
那么問(wèn)題來(lái)了,當(dāng)我們判斷完成需要對(duì)textField.text進(jìn)行賦值的時(shí)候,一不小心就有可能直接寫(xiě)出這樣的代碼。
if var text = textField.text 【
/// 邏輯操作
text = "XXXXXXX"
}
print(textField.text!)
打印textField.text就會(huì)發(fā)現(xiàn)并不是text賦值的值。
三、問(wèn)題分析
一開(kāi)始遇到問(wèn)題我以為我是對(duì)Optional Binding的理解有一些問(wèn)題,查看了蘋(píng)果的官方文檔
You use optional binding to find out whether an optional contains a value, and if so, to make that value available as a temporary constant or variable.
使用可選綁定去確認(rèn)一個(gè)可選類(lèi)型是存在值的,進(jìn)而可以將這個(gè)值作為一個(gè)臨時(shí)的常量或者變量。
文檔上這個(gè)temporary讓我以為是作用域的問(wèn)題,然而情況并不是這樣。我專門(mén)聲明了一個(gè)textField?類(lèi)型的變量。
var testTextField: UITextField?
接著創(chuàng)建一個(gè)textfield
let textField = UITextField(frame: CGRect(x: 100, y: 100, width: 100, height: 50))
textField.text = "測(cè)試數(shù)據(jù)"
testTextField = textField
通過(guò)可選綁定獲取解包之后的testTextField
if let testTextField = testTextField {
testTextField.text = "測(cè)試數(shù)據(jù)1"
}
print(testTextField!.text!)
此處的打印結(jié)果應(yīng)該是什么呢?--測(cè)試數(shù)據(jù)1。
結(jié)果表明我們對(duì)可選綁定后的變量賦值是成功的,那么問(wèn)題又來(lái)了為何之前text賦值不成功呢?
既然有成功的案例自然就證明了這個(gè)鍋并不該由Optional Binding來(lái)背。
所以問(wèn)題到底是出在哪里呢?
仔細(xì)看兩次可選綁定的類(lèi)型,一個(gè)使用了let一個(gè)使用了var,是因?yàn)檫@個(gè)原因么?明顯不是,兩次可選綁定的對(duì)象類(lèi)型一個(gè)是UITextField?,另一個(gè)是String?看出問(wèn)題了么?
-
UITextField是引用類(lèi)型,可選綁定的結(jié)果是指針,指向的內(nèi)存是同一塊內(nèi)存地址。 -
String是值類(lèi)型,可選綁定的是具體的值,相當(dāng)于新建了一個(gè)變量賦的值和textField.text一樣而已。
四、總結(jié)
Swift的設(shè)計(jì)理念就是盡可能拋棄一些歷史上存在的包袱,是一門(mén)更加高級(jí)和現(xiàn)代化的語(yǔ)言。而OC身上就明顯刻印著C的烙印,像NSString *和UITextField *,其中*號(hào)就能讓開(kāi)發(fā)者一目了然這是一個(gè)引用類(lèi)型,Swift中的引用類(lèi)型和值類(lèi)型并沒(méi)有符號(hào)來(lái)區(qū)分,因此在使用的過(guò)程中一定要更加謹(jǐn)慎才行。