官方描述
Automatic key-value observing is implemented using a technique called
isa-swizzling...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.
對于KVO實(shí)現(xiàn)的原理,蘋果官方文檔描述的比較少娜扇,從中只能知道蘋果使用了一張叫做isa-swizzling的黑魔法...
其實(shí)错沃,當(dāng)某個(gè)類的對象第一次被觀察時(shí),系統(tǒng)就會在運(yùn)行期動態(tài)地創(chuàng)建該類的一個(gè)派生類(類名就是在該類的前面加上NSKVONotifying_ 前綴)雀瓢,在這個(gè)派生類中重寫基類中任何被觀察屬性的 setter 方法枢析。
派生類在被重寫的 setter 方法實(shí)現(xiàn)真正的通知機(jī)制,就如前面手動實(shí)現(xiàn)鍵值觀察那樣刃麸,調(diào)用willChangeValueForKey:和didChangeValueForKey:方法醒叁。這么做是基于設(shè)置屬性會調(diào)用 setter 方法,而通過重寫就獲得了 KVO 需要的通知機(jī)制嫌蚤。當(dāng)然前提是要通過遵循 KVO 的屬性設(shè)置方式來變更屬性值辐益,如果僅是直接修改屬性對應(yīng)的成員變量,是無法實(shí)現(xiàn) KVO 的脱吱。
同時(shí)派生類還重寫了 class 方法以“欺騙”外部調(diào)用者它就是起初的那個(gè)類智政。然后系統(tǒng)將這個(gè)對象的 isa 指針指向這個(gè)新誕生的派生類,因此這個(gè)對象就成為該派生類的對象了箱蝠,因而在該對象上對 setter 的調(diào)用就會調(diào)用重寫的 setter续捂,從而激活鍵值通知機(jī)制。此外宦搬,派生類還重寫了 dealloc 方法來釋放資源牙瓢。