一、#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參數的本質:
- 如果實參有物理內存地址,且沒有設置屬性觀察器:直接將實參的內存地址傳入函數。
- 如果實參是計算屬性或者設置了屬性觀察器:採取了
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修飾的類不能被繼承