Swift可選鏈

背景

寫過(guò)swift的同學(xué)都只有一個(gè)可選鏈的概念,當(dāng)我們想訪問(wèn)某個(gè)變量的屬性或者方法但是不知道到這個(gè)變量是否為空的時(shí)候,直接使用'.'運(yùn)算符訪問(wèn)屬性或者方法的話,在運(yùn)行時(shí)如果變量是nil則會(huì)崩潰,這時(shí)一個(gè)便捷的方法就是在變量后使用‘?.’的方式來(lái)訪問(wèn)。今天就是和大家一個(gè)看下這個(gè)在swift和OC混用時(shí)候的一些問(wèn)題

基礎(chǔ)

可選類型

首先來(lái)個(gè)小知識(shí)點(diǎn):大家定義可選屬性的時(shí)候會(huì)使用

var name: String?

那么可選類型還能怎么寫呢?大家使用過(guò)這樣的方式嗎?

var name: Optional<String>

這第二種方式就是標(biāo)準(zhǔn)庫(kù)中定義的命名型類型 Optional<Wrapped> 也就是可選類型。而第一種方式只是它的語(yǔ)法糖。
類型 Optional<Wrapped> 是一個(gè)枚舉,有兩個(gè)成員,none 和 some(Wrapped),用來(lái)表示可能有也可能沒(méi)有的值。任意類型都可以被顯式地聲明(或隱式地轉(zhuǎn)換)為可選類型。如果你在聲明可選變量或?qū)傩缘臅r(shí)候沒(méi)有提供初始值,它的值則會(huì)自動(dòng)賦為默認(rèn)值 nil。(有關(guān)不透明類型請(qǐng)參閱相關(guān)paper)

可選鏈

可選調(diào)用就是我們?cè)谀硞€(gè)可選值可能為空的基礎(chǔ)上去訪問(wèn)它的屬性或者方法的操作,而將多個(gè)可選調(diào)用組合起來(lái)就是可選鏈。
如果可選鏈中有一個(gè)調(diào)用失敗了,那么整體返回的就是nill,而全部成功的話,不論這個(gè)調(diào)用的屬性、方法返回的值是不是可選值,它的返回結(jié)果都是一個(gè)可選值。

var name: String? = personA?.info?.name;

案例

先看這么一個(gè)問(wèn)題,假設(shè)我們有一個(gè)OC的類定義:

@interface ClassA : NSObject
@property (nonatomic, strong) NSArray<person*> *people;
@end

當(dāng)我們有一個(gè)ClassA實(shí)例的時(shí)候,假設(shè)其people是一個(gè)nill值,那么我們?cè)趕wift中這么判斷時(shí):

guard  instanceA?.people.count ?? 0 else {
            return
}

會(huì)有什么問(wèn)題?當(dāng)我們運(yùn)行的時(shí)候會(huì)發(fā)生什么呢?
系統(tǒng)會(huì)提示如下錯(cuò)誤

Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value

這是因?yàn)镺C中默認(rèn)的可以為nil的值在swift中就會(huì)變成nil,盡管它聲明時(shí)處于非空假設(shè)中。
而可選鏈在每個(gè)環(huán)節(jié)都應(yīng)該加‘?.’?;蛘哒f(shuō)只有加了‘?.’的表達(dá)式才稱為一個(gè)可選鏈的一部分。
如果我們?cè)L問(wèn)一個(gè)包含可選鏈的判斷語(yǔ)句的時(shí)候,只有可選鏈中的部分才會(huì)進(jìn)行為nil就返回的邏輯,比如上述代碼中第一部分

instanceA?.

這一部分的意思是如果instanceA為nil則表達(dá)式返回nil.反之則返回‘.’運(yùn)算符的結(jié)果對(duì)應(yīng)的可選值。
假設(shè)我們的第二個(gè)屬性也是空的,也就是people為nil;

instanceA?.people 

代碼到這里也不會(huì)有問(wèn)題,因?yàn)椤?’在非空的實(shí)例上訪問(wèn)了一個(gè)nill值,返回的是一個(gè)nil,從而表達(dá)式整體都是一個(gè)nil的值了。也就是'''instanceA?.people '''表達(dá)式的整體值為nil。
但是,當(dāng)我們加上第三部分的時(shí)候, 也就是表達(dá)式變成:

 instanceA?.people.count 

這時(shí)people為nil意味著對(duì)一個(gè)nil的變量做一個(gè)屬性訪問(wèn),因?yàn)闆](méi)有'?',相當(dāng)于強(qiáng)制解包,所以才會(huì)出現(xiàn)這個(gè)問(wèn)題。
而至于之后的?? 它計(jì)算左表達(dá)式的時(shí)候就已經(jīng)崩潰了,所以沒(méi)有機(jī)會(huì)執(zhí)行了。

問(wèn)題

那么為什么當(dāng)時(shí)寫的時(shí)候沒(méi)有加‘?.’而是直接用了‘.’呢。因?yàn)槎x在OC中,而判斷在swift中,OC定義的文件默認(rèn)會(huì)有非空的宏包裹定義。swift默認(rèn)它時(shí)非空的,所以才會(huì)出現(xiàn)此問(wèn)題。

總結(jié)

可選鏈就是多個(gè)可選調(diào)用的組合,要在每一個(gè)可能為空的表達(dá)式處加上可選調(diào)用'?'才能保證不會(huì)對(duì)nil值使用‘.’運(yùn)算符。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 可選鏈 可選鏈?zhǔn)秸{(diào)用是一種可以在當(dāng)前值可能為 nil 的可選值上請(qǐng)求和調(diào)用屬性、方法及下標(biāo)的方法。如果可選值有值,...
    xiaofu666閱讀 284評(píng)論 0 0
  • 介紹 可選鏈,英文叫Optional Chaining,是表示變量、屬性等值可為空,也就是值可能為nil。若有值,...
    jdong閱讀 387評(píng)論 0 0
  • 一. 可選鏈(Optional Chaining) 如果可選項(xiàng)為nil,調(diào)用方法、下標(biāo)、屬性失敗,結(jié)果為nil 如...
    蔣斌文閱讀 809評(píng)論 0 0
  • 可選鏈?zhǔn)秸{(diào)用是一種可以在當(dāng)前值可能為 nil 的可選值上請(qǐng)求和調(diào)用屬性、方法及下標(biāo)的方法。如果可選值有值,那么調(diào)用...
    伯wen閱讀 129評(píng)論 0 0
  • 可選鏈?zhǔn)秸{(diào)用是一種可以在當(dāng)前值可能為 nil 的可選值上請(qǐng)求和調(diào)用屬性、方法及下標(biāo)的方法。 如果可選值有值,那么調(diào)...
    DevXue閱讀 179評(píng)論 0 0

友情鏈接更多精彩內(nèi)容