OC基礎-(四)KVC、KVO
KVO
Q: 什麼是KVO?
- KVO(key-value observing),從名稱上就可以知道這是一種鍵值觀察的機制
- KVO是OC對觀察者模式的又一實現
- Apple使用isa混寫技術(isa-swizzling)來實現KVO
當我們註冊一個物件的觀察者的時候,也就是呼叫了系統的addObserver:forKeyPath:options:context:
方法,來觀察一個物件的某個屬性,系統會在執行時建立一個新的物件NSKVONotifying_物件類名
,並將原本指向物件類
的isa指標指向這個NSKVONotifying_物件類名
,NSKVONotifying_物件類名
實際上是原物件類的子類
,只是我們在這個子類中,重寫了需要觀察的屬性的set
方法。以此達到觀察值變化的目的,如下圖所示:
Q: 那麼,為什麼系統新新增的set方法就能夠監聽到值變化呢?
系統為我們實現的set方法中有這兩個方法:
- - (void)willChangeValueForKey:(NSString *)key
- - (void)didChangeValueForKey:(NSString *)key
這兩個方法分將對屬性賦值的程式碼包了起來
- (void)setValue:(id)obj {
[self willChangeValueForKey:@"keyPath"];
// 呼叫父類的實現, 也即是原類的實現
[super setValue:obj];
[self didChangeValueForKey:@"keyPath"];
}
Q: 通過KVC設定的value,KVO能否監聽到變化?
答案是能!那麼為什麼會KVC設定的值,會生效呢?實際上就是要因為在賦值時會呼叫到屬性的set方法,所以會使得KVO被觸發。
Q: 通過成員變數直接賦值value,KVO能否有效?
答案是不能,系統為我們提供的KVO實際上還是對set方法的覆蓋,但我們直接對成員變數賦值是不會走set方法的。但是,我們可以手動的實現KVO,也就是將上面的willChangeValueForKey:
和didChangeValueForKey:
按照上面的樣子。將設定值的程式碼包起來即可。
KVC
Q: 什麼是KVC
- KVC是鍵值編碼(key-value coding)的縮寫,和鍵值編碼相關的方法
- - (id)valueForKey:(NSString *)key,這個方法可以獲取和key同名,或者相似名稱的屬性值,並返回
- - (void)setValue:(id)value forKey:(NSString *)key 可以獲取和這個key同名或者相似名稱的屬性賦值
我們現在來看看KVC的獲取屬性的流程
- 首先會判斷我們使用的key(或相似)是否有get方法,如果get方法存在,則直接呼叫,結束訪問流程
- 如果訪問的key的get方法未找到,則會判斷是否有同名或相似的例項變數存在,如果存在,則返回
- 在get方法未找到的過程中,系統給我們提供了一個可遮蔽的開關
+ (BOOL)accessInstanceVariablesDirectly
,如果和key相同或同名的例項變數存在,則返回YES,但是如果我們重寫這個方法並返回NO,即使這個同名例項變數存在,也不會被獲取到。 - 如果例項變數不存在,系統會呼叫當前例項的
valueForUndefinedKey:
方法,然後丟擲NSUndefinedKeyException
異常,結束呼叫流程。
這裡有兩個點需要注意:
- 訪問器方法(Accessor Method)是否存在的判斷規則時什麼樣的
- 例項變數(Instance var)是否存在的規則時什麼樣的
訪問器方法(Accessor Method)
訪問器方法也實現了相似
的概念,但是方法的命名必須遵循駝峰命名下面這幾種是可以被判斷為實現了key
的訪問器方法:
- getKey
- key
- isKey
例項變數(Instance ver)判斷
下面幾種例項變數的名稱是可以被識別的
- _key
- _isKey
- key
- isKey
再讓我們現在來看看KVC的Set方法的流程
其方法查詢流程,與get的流程相同
相關文章
- 【iOS基礎】KVC / KVO詳解iOS
- KVC 和 KVO
- KVC/KVO 總結
- KVC 和 KVO(三)
- iOS KVC與KVOiOS
- iOS KVC與KVO簡介iOS
- KVO與KVC原理筆記筆記
- iOS KVC和KVO詳解iOS
- 簡單易懂KVC基礎篇
- 用程式碼探討KVC/KVO的實現原理
- 用程式碼探討 KVC/KVO 的實現原理
- OC底層探索(十六) KVO底層原理
- OC觀察者模式之KVO的使用與思考模式
- 【轉載】oc語言基礎知識全面 看完oc基礎教程後再溫習一遍C語言
- iOS底層原理總結篇-- 深入理解 KVC\KVO 實現機制iOS
- iOS開發面試攻略(KVO、KVC、多執行緒、鎖、runloop、計時器)iOS面試執行緒OOP
- iOS | 面試知識整理 - OC基礎 (一)iOS面試
- OC中常見基礎知識點彙整
- Kotlin基礎四Kotlin
- 逆向基礎(四)
- Dart基礎(四)Dart
- java基礎(四)Java
- 前端基礎入門四(JavaScript基礎)前端JavaScript
- 測試基礎(四)Jmeter基礎使用JMeter
- 【iOS – OC】OC基礎-單例的實現 & 提醒自己注意多執行緒問題iOS單例執行緒
- KVC
- Camera基礎知識四
- gRPC(四)基礎:gRPC流RPC
- JavaScript 基礎(四) – HTML DOM EventJavaScriptHTML
- JavaSE基礎知識分享(四)Java
- Python基礎之四:Python3 基礎資料型別Python資料型別
- iOS-KVCiOS
- KVC原理剖析
- JavaScript夯實基礎系列(四):原型JavaScript原型
- Java面試題-基礎篇四Java面試題
- Linux 筆記分享四:Shell 基礎Linux筆記
- 《MySQL 基礎篇》四:查詢操作MySql
- Django基礎之四(日誌)【待續】Django