KVO 是 Objective-C 對觀察者模式(Observer Pattern)的實現。也是 Cocoa Binding 的基礎。當被觀察對象的某個屬性發生更改時,觀察者對象會得到通知。ui
有意思的是,你不須要給被觀察的對象添加任何額外代碼,就能使用 KVO 。這是怎麼作到的?指針
第一次被觀察
時,系統就會在運行期動態
地建立該類的一個派生類
,在這個派生類中重寫基類中任何被觀察屬性的setter 方法。派生類在被重寫的setter方法內實現真正的通知機制
NSKVONotifying_Person
willChangeValueForKey:
和 didChangevlueForKey:
;在一個被觀察屬性發生改變以前, willChangeValueForKey:
必定會被調用,這就 會記錄舊的值。而當改變發生後,didChangeValueForKey:
會被調用,繼而 observeValueForKey:ofObject:change:context:
也會被調用。補充:KVO的這套實現機制中蘋果還偷偷重寫了class方法,讓咱們誤認爲仍是使用的當前類,從而達到隱藏生成的派生類code
KVC運用了一個isa-swizzling技術. isa-swizzling就是類型混合指針機制, 將2個對象的isa指針互相調換, 就是俗稱的黑魔法.
KVC主要經過isa-swizzling, 來實現其內部查找定位的. 默認的實現方法�由NSOject提供isa指針, 如其名稱所指,(就是is a kind of的意思), 指向分發表對象的類. 該分發表實際上包含了指向實現類中的方法的指針, 和其它數據。server
- 具體主要分爲三大步
- 或者這麼說
好比說以下的一行KVC的代碼:對象
[object setValue:@"13123" forKey:@"uuid"]; 就會被編譯器處理成: // 首先找到對應sel SEL sel = sel_get_ uuid("setValue:forKey:"); // 根據object->isa找到sel對應的IMP實現指針 IMP method = objc_msg_lookup (object->isa,sel); // 調用指針完成KVC賦值 method(object, sel, @"13123", @"uuid");