KVC/KVO

KVC

問題:api

  1. 經過KVC修改屬性會觸發KVO麼?
  2. KVC的賦值和取值過程是怎樣的?原理是什麼?

1. 什麼是KVC?

Key-value coding是一種可以對屬性/成員變量間接訪問的機制,是一種非正式協議,和setter/getter方法比起來更加靈活,使用字符串做爲key能夠在運行期間改變。bash

常見的api函數

- (void)setValue:(id)value forKey:(NSString *)key;
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;

- (id)valueForKey:(NSString *)key; 
- (id)valueForKeyPath:(NSString *)keyPath;

複製代碼

setValue:(id)value forKeyPath:(NSString *)keyPath 和 setValue:(id)value forKey:(NSString *)key 的區別ui

  • keyPath 至關於根據路徑去尋找屬性,一層一層往下找
  • key 是直接哪去屬性的名字設置,若是按路徑找會報錯

2. valueForKey:的取值規則

  1. 接收器中若是有key訪問器(-getKey, -key, or -isKey)直接訪問 返回包裝好的對象
  2. 沒有訪問器,使用接收器的類方法 +accessInstanceVariablesDirectly,若是爲YES 則根據 _key, _isKey, key, or isKey 順序查找 返回包裝好的對象
  3. 未找到觸發-valueForUndefinedKey:默認實現是拋出NSUndefinedKeyException異常

3. setValue:forKey:的賦值步驟

  1. 查找-setKey方法 有就直接調用
  2. +accessInstanceVariablesDirectly 返回YES 則依照 _key, _isKey, key, or isKey 順序查找賦值
  3. -setValue:forUndefinedKey: 默認 拋出NSUndefinedKeyException

KVO

問題:spa

  1. iOS用什麼方式來實現對一個對象的KVO?(KVO的本質是什麼?)
  2. 如何手動出發KVO?
  3. 直接修改爲員變量會觸發KVO麼?

答案

  1. iOS用什麼方式實現對一個對象的KVO?(KVO的本質是什麼?)
利用runtime動態生成一個子類,而且讓instance對象的isa指針指向這個全新的子類,當修改instance的屬性時會調用Foundation的_NSSetXXXValueAndNotify函數,在函數中
- willChangeValueForKey:
- 父類原來的setter
- didChangeValueForKey:
內部會觸發監聽器(Oberser)的監聽方法(observeValueForKeyPath:ofObject:change:context:)
複製代碼
  1. 如何手動觸發KVO?
手動調用willChangeValueForKey:和didChangeValueForKey:
複製代碼
  1. 直接修改爲員變量會觸發KVO麼?
不會觸發KVO,由於直接修改爲員變量並無走set方法
複製代碼
  1. 經過KVC修改屬性會觸發KVO麼?
會觸發KVO,如上流程圖
複製代碼
  1. KVC的賦值和取值過程是怎樣的?原理是什麼?
本站公眾號
   歡迎關注本站公眾號,獲取更多信息