九層之臺,起于累土
Apple 用什么方式實現(xiàn)對一個對象的的 KVO 羡榴?
官方文檔:
Key-Value Observing Implementation Details
Automatic key-value observing is implemented using a technique called?isa-swizzling.
The isa pointer, as the name suggests, points to the object's class which maintains a dispatch table. This dispatch table essentially contains pointers to the methods the class implements, among other data.
When an observer is registered for an attribute of an object the isa pointer of the observed object is modified, pointing to an intermediate class rather than at the true class. As a result the value of the isa pointer does not necessarily reflect the actual class of the instance.
You should never rely on the isa pointer to determine class membership. Instead, you should use theclassmethod to determine the class of an object instance.
翻譯:
鍵值觀察實現(xiàn)細節(jié):
自動鍵值觀察使用一種叫做 isa-swizzling 的技術(shù)來實現(xiàn)的立由。
通過 isa 指針的名字可以看出沛豌,只想對象類別的指針維護了一個分發(fā)表舌仍。這個分發(fā)表包括了指向了這個類的方法的的指針铃拇,包括了志向類實現(xiàn)的指針蜈首,以及其他數(shù)據(jù)实抡。
當一個觀察者被注冊觀察某一對象的屬性時,被觀察者的 isa 指針發(fā)生了修改欢策,它指向了一個中間類而不是被觀察者的真實的類吆寨。這就造成了被觀察者的類的 isa 指針不能準確的反映出這個實例(對象)的真實的 類別(Class)。
你永遠不能通過 isa 指針來判斷一個類的關(guān)系踩寇。而是通過實例(對象)的 class 方法來判斷來判斷這個實例的類別啄清。
(僅供參考,如有錯誤俺孙,請予以指正)
?? 以下內(nèi)容非原創(chuàng)辣卒,寫在這兒僅用于學習,出處為?iOS面試題集錦(附答案)- ChenYilong
從 Apple 的官方文檔可以看出: Apple 并不希望過多暴露 KVO 的實現(xiàn)細節(jié)睛榄。不過可以通過 runtime 提供的方法來進行深入了解:
當觀察一個對象時荣茫,一個新的類會被動態(tài)創(chuàng)建。這個被動態(tài)創(chuàng)建的新類是繼承自該對象原有的類场靴,并重寫了被觀察屬性的 setter 方法啡莉。重寫的 setter 方法會負責在調(diào)用原 setter 方法之前和之后,通知所有觀察對象值得更改旨剥。最后通過 isa 混寫 (isa-swizzling [?swiz?l] )把這個對象的 isa 指針指向這個新創(chuàng)建的子類咧欣,對象就神奇的變成了新創(chuàng)建的子類的實例。
詳細解釋:
鍵值觀察通知依賴于 NSObject 的兩個方法:willChangeValueForKey: 和 didChangeValueForKey: 轨帜。在一個被觀察屬性發(fā)生改變之前魄咕, willChangeValueForKey: 一定會被調(diào)用,這就會記錄就的值蚌父,而改變發(fā)生后哮兰,didChangeValueForKey: 會被調(diào)用,繼而 observeValueForKey:ofObject:change:context: 也會被調(diào)用苟弛『戎停可以手動實現(xiàn)這些調(diào)用,但很少有人這么做嗡午。一般我們只在希望能控制回調(diào)的調(diào)用時機時才會這么做囤躁。大部分情況下冀痕,改變通知會自動調(diào)用荔睹。
具體研究過程:KVO 實現(xiàn)原理