swift中的optional

來源:互聯網
上載者:User

標籤:err   編譯器   取值   word   object-c   過程   block   reflect   實現   

optional一些理解和總結:

Optional作為一種類型,既可以儲存一個值,也可以為空白(也就是swift裡的nil);

其實為一個枚舉類型,包含nil或者一個值,如下;

enum Optional<T>: _Reflectable, NilLiteralConvertible {    case None    case Some(T)    //...}

它只有兩種狀態,包含一個值或者為空白;
optional有效解決了值為空白的清空;
我們可以通過判斷一個對象是否為空白了做出相應解決,通過if let a = b(optional)的方式實現一個解包過程,並在條件中使用a,而不再解包;
針對anyobject,由於直到運行時才知道AnyObject的物件類型,所以有可能在不經意間寫出不安全的程式碼,
如:let timeSinceNow = myObject.timeIntervalSinceNow;
當一個anyobject類型的對象去調用某個方法,而該對象不存在此方法(optional對象調用方法會隱式展開),如下;
let timeSinceNow = myObject.timeIntervalSinceNow?();  ----此時當方法不存在時,timeSinceNow被推測為對應類型,並被賦予一個nil值;
接著可以使用if let方式判斷來使用該對象;這個就避免了anyobject運行時才確定類型而報錯的問題;

對於隱式解包:訪問時,編譯器會自動幫我們完成在變數後插入!的行為
當我在項目中明確確定該屬性一定會被初始化;且在使用範圍內不會為空白時,在聲明屬性時就可以使用!表示隱式解包;
這類屬性主要這對UI控制項,通常情況,控制項都不會為空白,這樣避免了繁雜的解包過程以及判斷過程;
隱式解包的來源摘自百度:
  王巍在他的Swift Tip解釋了一下:

這一切都是曆史的鍋。因為Object-C中Cocoa的所有類型變數都是可以指向nil的,有一部分Cocoa的API中在參數或者返回時即使被聲明為具體的類型,但是還是可能在某些特定的情況下是nil, 而同時也有另一部分API永遠不會接受或者返回nil。在Objective-C時,這兩種情況並沒有加以區別,因為在OC中向nil發送訊息是允許的,結果就是什麼都不會發生,而在Cocoa API從OC轉為Swift的module聲明的自動化工具裡,是無法判定是否存在nil的可能的,因此也無法決定哪些類型應該是實際的類型,而哪些類型應該聲明為Optional。

在這種自動化轉換中,最簡單粗暴的應對方式是全部轉為 Optional,然後讓使用者通過 Optional Binding 來判斷並使用。雖然這是最安全的方式,但對使用者來說是一件非常麻煩的事情,我猜不會有人喜歡每次用個 API 就在 Optional 和普通類型之間轉來轉去。這時候,隱式解包的 Optional 就作為一個妥協方案出現了。使用隱式解包 Optional 的最大好處是對於那些我們能確認的 API 來說,我們可直接進行屬性訪問和方法調用,會很方便。但是需要牢記在心的是,隱式解包不意味著 “這個變數不會是 nil,你可以放心使用” 這種暗示,只能說 Swift 通過這個特性給了我們一種簡便但是危險的使用方式罷了。


當然隱式解包也會有問題,嘗試訪問一個為空白的隱式解包Optional,就會遇到一個runtime error;
這種問題在自己項目中最常見的就是在非同步線程(主要為網路請求)中主動去調用控制項;當對象銷毀而線程順延強制時就會崩潰;在調用對象前主動判斷對象為空白否。

針對optional的屬性和方法,可以通過鏈(Optional Chaining)來實現安全訪問,如同anyobject使用一樣;
let b: Int?
if let a = b?.sum(){a的使用};-----擺脫很多不必要的判斷和取值,從而精簡代碼。

swift中可以使用??來設定一個預設值;
同上:if let a = b?sum() ?? 1 -----如果b為空白了,給a賦值1;
設定預設值的方法在項目中很方便;
當你封裝一個方法,而針對不同的調用者是??可有效解決調用者身份判斷問題。
列:
  func addNum(a: Int, b: Int, c: Int = nil) -> Int{if c == nil {return a + b} else (return a + b - c)}
而你在調用該方法時,系統會提供自動兩個func;--------次方法在代碼高度封裝以及一些特殊判斷中非常有效;

關於oc方法調用:oc中對象應用可以為NULL,而swift中必須為非空;所以當在swift中使用oc對象時必須保證其位非空;

以次文紀念我死在開發道路上的腦細胞。

swift中的optional

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.