面試復(fù)習(xí)-(KVO KVC 分類 load和initialize 關(guān)聯(lián)對象)

KVO 原理

里氏替換

  1. 利用runtime 動態(tài)生成一個子類A,且修改 instacne a對象的isa指向該全新子類
  2. NSKVONotifying_A 的屬性被修改時,子類的set方法內(nèi)部調(diào)用
    willChangeValueForKey -> 原本的set實現(xiàn) -> didChangeValueForKey
  3. didChangeValueForKey會調(diào)用監(jiān)聽器的observeValueForKeyPath:ofObject:change:context:監(jiān)聽方法

動態(tài)生成的 NSKVONotifying_A 結(jié)構(gòu)體:有isa、superClass、setAge方法、class方法
setAge 方法:對觀察的變量重寫的set方法
class 方法:重寫,以隱藏自己的存在(返回再上一層),使 A 的實例調(diào)用 class 時仍返回 A 而非真實的 class NSKVONotifying_A
_isKVOA = YES;
dealloc 收尾方法重寫

  1. 手動觸發(fā)KVO
    調(diào)用willChangeValueForKey 和 didChangeValueForKey,缺一不可。
[p1 willChangeValueForKey:@“age”];
// do something
[p1 didChangeValueForKey:@“age”];
  1. 取消kvo
    automaticallyNotifiesObserversForKey 返回NO

KVC 原理

  1. 先調(diào)用 setKey _setKey ,找了 直接調(diào)用
  2. 未找到 則 查看 accessInstanceVariablesDirectly 此方法是否可以直接訪問成員變量 (默認=YES)
  3. 可訪問 按照 _key _isKey key isKey順序取賦值,未找到報錯 NSUnknownKeyException
  4. valueForKey類似

分類原理

  1. 分類文件在編譯后的底層結(jié)構(gòu)是 struct category_t,里面有分類的對象方法,類方法,屬性,協(xié)議信息
  2. 在程序運行階段,runtime將category的數(shù)據(jù),合并到類信息中(類對象,元類對象)
  3. 與類擴展不同在于 一個編譯時合并ro,一個運行時合并rw
  4. 后編譯的分類方法,在消息查找時會覆蓋前面的同名方法(原方法也還在)

分類添加弱引用對象 weak:加個obj,obj弱引用該對象

load 和 initialize

load
  1. +load 在 runtime 加載類,分類時調(diào)用
  2. 每個類,分類的 +load 運行時只調(diào)用一次,直接根據(jù)load方法地址調(diào)用,不走objc_msgSend
  3. 先調(diào)用類的 +load,先父類 再 子類
  4. 再調(diào)用分類的load,先編譯 先調(diào)用
initialize
  1. +initialize 在類第一次收到消息調(diào)用
  2. 先調(diào)用父類的 +initialize ,再調(diào)用子類 initialize
  3. +initialize通過 objc_msgSend調(diào)用,如果子類未實現(xiàn) +initialize,會導(dǎo)致父類 initialize 多次調(diào)用

關(guān)聯(lián)對象

  1. 所有的關(guān)聯(lián)對象由全局對象 AssociationsManager管理,內(nèi)部有個hashMap map
  2. map使用 對象地址做為key ,ObejctAssociationMap 作為value
  3. ObejctAssociationMap 內(nèi)部也是屬性作為 key,ObejctAssociation作為value
  4. ObejctAssociation內(nèi)部保存 策略 和 value

NSObject占用多少內(nèi)存

16字節(jié),因為對象最少16字節(jié),一個指針是8字節(jié)(64位)

內(nèi)存對齊小結(jié)
  • 前面的地址必須是后面的地址正數(shù)倍,不是就補齊
  • 整個Struct的地址必須是最大字節(jié)的整數(shù)倍
在繼承條件下為

Person:isa 8字節(jié) + age 4字節(jié) + 內(nèi)存對齊 = 16字節(jié)
Student:isa 8字節(jié) + age 4字節(jié) + no 4字節(jié) (已對齊)= 16字節(jié)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容