本小節經過性能消耗的Demo來從底層講了協議底層容器
相關的知識點swift
先看demo性能
///使用泛型參數的方法--性能高
func f<C: CustomStringConvertible>(_ x: C) -> Int {
return MemoryLayout.size(ofValue: x)
}
///使用協議作參數的方法--性能低
func g(_ x: CustomStringConvertible) -> Int {
return MemoryLayout.size(ofValue: x)
}
f(5) // 8--正常一個Int類型在64位中Int的尺寸
g(5) // 40
複製代碼
明明是同一個Int爲嘛後面的方法size就大不少。編碼
咱們先看看g(5) 值爲 40 是怎麼組成的,這裏面存在一個不透明的容器
的概念(下圖中標註的有)。spa
40的長度是由三部分組成指針
1.存儲值的緩衝區(3個指針長度) 3 * 8 = 24code
2.元數據 8cdn
3.目睹表(vtable 能夠有0個或者多個 這裏有1個) 8blog
來來,看看我大筆一揮畫的靈魂示意圖: it
目睹表是讓動態派發
成爲可能的關鍵,爲一個特定的類型將協議的實現
進行編碼,表中會包含一個指向特定類型中的實現的入口
。io
OC中的協議不須要封裝在存在容器中,so~
MemoryLayout.size // 8
不推薦❎
//隱式打包
func printProtocol(array: [CustomStringConvertible]) {
print(array)
}
複製代碼
推薦✅ swift標準庫
中大多數使用場景。
//沒有打包
func printGeneric<A: CustomStringConvertible>(array: [A]) {
print(array)
}
複製代碼