Swift-常見關鍵字

一、#available和@available

@available是編譯時期作用,#available是運行時起作用。
1. @available
在Swift中用於修飾一個類型、擴展、協議、方法、屬性,用來表達它的可用性,比如平臺、操作系統、是否廢棄、已經不可用,例子如下:

 extension String {
    // 1.表示iOS 11.0及以上可用,除操作系統外沒有其他條件,後面參數寫*
    @available(iOS 11.0, *)
    
    // 2.除了操作系統外還有其他的條件,這個時候平臺和系統版本號要分開。
    // 如下表示,iOS 11後已經廢棄,方法新命名爲stringxxx
    // iOS表示是iOS平臺
    // introduced表示從那個操作系統版本號開始
    // deprecated的作用:表示已經廢棄如果在iOS11之後使用會有警告'string(date:)' is deprecated in iOS:
    // renamed的作用是警告時有提示:renamed to 'stringxxx' Use 'stringxxx' instead
    @available(iOS, introduced: 11.0, deprecated, renamed: "stringxxx")
    
    // 3.如果對所有平臺和系統版本都起作用,則第一個參數寫*
//    @available(*, deprecated, renamed: "abcd")
    
    // 4.如果要添加更加詳細的描述,可以使用message參數:
    // message參數可以添加對該方法的描述
    // unavailable表示該方法已經不可用,使用時會報錯,報錯信息爲message的值
    @available(*, message: "withUnretained has been deprecated for Driver. Consider using `drive(with:onNext:onCompleted:onDisposed:)`, instead", unavailable)
    func string(date: Int) -> String? {
        return nil
    }
}

2. #available
用於執行過程中的平臺和操作系統條件判斷,在OC中不能使用。

if #available(iOS 13.0, *) {
    actionBackgroundColor = UIColor.systemRed
} else {
    actionBackgroundColor =  #colorLiteral(red: 1, green: 0.2352941176, blue: 0.1882352941, alpha: 1)
}
二、#colorLiteral

view.backgroundColor = #colorLiteral(red: 1, green: 0.2352941176, blue: 0.1882352941, alpha: 1)
這樣寫在Xcode中會顯示這個顏色,並且點擊顏色可以自己選擇其它顏色,這讓我們設置的顏色時很直觀。

三、mutating

值類型(枚舉、結構體)中寫方法時,如果涉及到修改自身內存時,需要使用mutating 修飾。
留有疑問❓那麼mutating修飾前後,該方法有什麼本質區別?爲什麼要設計mutating?
簡述:mutating本質上是給self參數加了inout修飾。

  • 值類型的方法中默認有self作爲參數,參數是let類型的值類型,不可修改,所以方法涉及修改自身值時會報錯;
  • 當使用mutating修飾方法之後, 編譯器背後把參數變爲inout修飾了,參數self變爲var,並且inout是指針傳遞,所以可以修改。
    詳述:Swift關鍵字(mutating)
四、inout

方法的參數是值類型時,如果方法中涉及到修改該參數的內存(如存儲屬性)時,需要加inout修飾。

func incrementChecked(_ i: inout Int) throws -> Int {
    if i == Int.max {
        throw RxError.overflow
    }
    defer { i += 1 }
    return i
}

var aaa = 10
let bbb = try? incrementChecked(&aaa)
print("aaa = \(aaa)", "bbb = \(bbb!)") // aaa = 11 bbb = 10

inout參數的本質:

  1. 如果實參有物理內存地址,且沒有設置屬性觀察器:直接將實參的內存地址傳入函數。
  2. 如果實參是計算屬性或者設置了屬性觀察器:採取了Copy In Copy Out的策略,
  • 調用該函數時,先複製實參的值產生副本『參數是傳計算屬性時會調用get』。
  • 將副本的內存地址傳入函數,在函數內部可以修改副本的值。
  • 函數返回後再將副本的值覆蓋實參的值『參數是計算屬性會調set』
五、defer、do、fatalError、@discardableResult、final
@discardableResult // 作用:外部調用時未使用結果不會有警告
func testKeys() -> Int {
    defer {
        print("函數結束之前會執行的代碼塊, 包括向上throws錯誤,但程序執行某一句代碼奔潰除外")
    }
    
    fatalError("測試拋出終止執行的錯誤")
    
    do {// 局部作用域,程序會順序執行,這裏可以用來寫一個邏輯相對獨立的代碼塊
        print("do")
    }
    
    return 10
}
// final只能用於類中,修飾的方法、屬性,不能被重寫;
// final修飾的類不能被繼承
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章