Runtime總結筆記`屬性`

文章爲原創,轉載請註明出處

對象(Object) & 消息傳遞(Messaging)

  • 對象:基本構造單元,開發者可以用來存儲並傳遞消息
  • 消息傳遞:在對象間傳遞數據並執行任務的過程叫“消息傳遞”

屬性

  1. 定義: 屬性用於封裝對象的數據,Objective-C對象將需要的數據保存爲各種實例變量(ivar),實例變量一般用存取方法獲得(getter & setter),通過點語法訪問屬性。可總結爲 property = ivar + getter + setter

  2. 屬性解決的問題:定義實例變量,對象佈局在編譯期固定,碰到實例變量會轉爲“偏移量”,表示變量和對象起始內存地址的距離,編譯期的偏移量,在使用新的定義和舊定義鏈接時會出錯。把實例變量當成存儲偏移量的特殊變量交給類保管,類定義變了,偏移量也就變了,類定義變了存儲也就變了,這就是穩固的 “程序二進制接口ABI”,這樣就可以在"class-continuation"或實現文件中定義實例變量了

@Property, @synthesize和@dynamic

  • @property:使用屬性封裝對象裏的數據,編譯期自動生成存取方法,使用"點語法"訪問屬性,編輯器裏看不到這些“合成方法”,這一過程稱爲"autoSynthesize"
  • @synthesize:用來指定合成的實例變量名(ivar),推薦使用"_name"語法
  • @dynamic:不自動創建實例變量,不生成存取方法,編譯器訪問代碼時不會報錯,因爲在運行時去找這些代碼

屬性特質

  • nonatomic:非原子的,iOS開發一般使用,使用非原子的屬性不具有同步鎖

  • atomic:原子的,沒有這個定義,屬性默認是原子的(一個屬性不是非原子的,那就是原子的),不能保證線程安全,有額外開銷,在MacOS開發不會太影響性能

  • readwrite:讀寫 readonly: 只讀

  • 內存管理語義:只會影響設置方法,自己編寫時必須使用屬性相關的特性

    1. strong:擁有關係,設置時保留新值釋放舊值
    2. weak:非擁有關係,設置時不保留新值不釋放舊值,屬性指向的對象銷燬時,屬性也清空
    3. assign:和weak一樣,但只用於純量類型(CGFloat)
    4. unsafe_retained:語義與assign相同,適用於“對象類型”,對象被摧毀時,屬性值不會清空
      5.copy:語義與strong相同,設置時不保留舊值,複製新值,一般有可變類型的對象都使用copy,用來保護其封裝性

在對象內部直接訪問實例變量

內部訪問&外部訪問

  • 內部訪問:在讀取實例變量時直接訪問(ivar),在設置時用設置方法
  • 外部訪問:通過屬性來訪問

內部訪問訪問"存取方法"和使用“實例變量”的區別

  1. 不經過Objective-C方法派發,直接訪問實例變量更快,編譯器直接訪問實例變量的地址(*ivar_list)
  2. 直接訪問繞過內存管理語義,不調用設置方法,在ARC下訪問Copy不會將其拷貝,只會保留新值釋放舊值
  3. 直接訪問不會觸發KVO
  4. 通過屬性訪問有利於排查錯誤,可以在存取方法裏添加斷點

在初始化方法中直接訪問實例變量

因爲子類有可能覆寫屬性的設置方法,所以要用實例變量來訪問,要初始化的屬性要是在超類裏,就只能用設置方法了

惰性初始化

惰性初始化通過存取方法訪問

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章