Swfit 屬性與彙編分析inout本質

今天將講述Swift屬性以及剖析inout的本質, 如有興趣可點擊關注,以後會定期更新更有料的博客!!!

一、屬性 

Swift中跟實例相關的屬性可以分為2大類

  1. 存儲屬性(Stored property)
  • 類似於成員變量這個概念
  • 存儲在實例的內存中
  • 結構體、類可以定義存儲屬性
  • 枚舉不可以定義存儲屬性

  2.  計算屬性(Computed Property)

  • 本質就是方法(函數)
  • 不佔用實例的內存
  • 枚舉、結構體、類都可以定義計算屬性
struct Circle {      //存儲屬性      var radius: Double      //計算屬性      var diameter: Double {          set{             radius = newValue / 2          }          get{              radius * 2          }      }  }

1. 存儲屬性

將針對例子講解上面的結論

 將結構體Struct改為類Class,如下

 解釋下為什麼枚舉Enum不可以定義存儲屬性?

 

2. 計算屬性

 上面說到計算屬性相當於函數方法的意思如下,前後兩者完全等價

 

 總結

存儲屬性: 關於存儲屬性,Swift有個明確的規定

  • 創建類或者結構體時, 必須為所有的存儲屬性設置一個合適的初始值
  • 可以在初始化器內為存儲屬性設置一個初始值,也可以分配一個默認的屬性值作為屬性定義的一部分

計算屬性: set傳入的新值默認為newValue,也可以自定義

  • 只讀計算屬性: 只有get,沒有set
  • 可讀可寫屬性
  • 沒有隻寫屬性,單獨一個set方法是不可以的

枚舉的原始值rawValue的本質是只讀計算屬性

 

3. 延遲存儲屬性(Lazy Stored Property)

使用lazy可以定義一個延遲存儲屬性, 在第一次用到屬性的時候才會進行初始化

 

4. 屬性觀察器(Property Observer)

可以為非lazyvar存儲屬性設置屬性觀察器,也是存儲屬性

 注意: 在初始化器中設置屬性值不會觸發willSet和didSet方法!!!

 

二、inout本質

inout:輸入輸出參數的本質就是引用傳遞(地址傳遞)

通過inout查看彙編代碼:leap命令: 將地址傳入進去

 inout本質總結:

如果實參有物理內存地址且沒有設置屬性觀察器:直接將實參的內存地址傳入函數(實參進行引用傳遞)

如果實參是計算屬性 或者 設置了屬性觀測器:採取了蘋果官方說的 Copy In Copy Out的做法

  1. 調用該函數時,先複製實參的值,產生局部變量副本(相當於get)
  2. 將副本的內存地址傳入函數(副本進行引用傳遞),在函數內部可以修改副本的值
  3. 函數返回後,再將副本的值覆蓋實參的值