ObjC中KVO原理簡析

2021-09-11 15:40:22 字數 2221 閱讀 8128

kvo的全稱是key-value observing,也稱「鍵值監聽」,可以用於監聽某個物件屬性值的改變。

通常我們通過addobserver:forkeypath:options:context來監聽某個例項的某個屬性變化。當該屬性的值發生變化的時候會通過- (**void**)observevalueforkeypath:(nsstring *)keypath ofobject:(**id**)object change:(nsdictionary*)change context:(**void** *)context通知我們。

顯然實現這個功能的基礎是屬性值得改變,而屬性值得改變需要呼叫setter方法。可是即使setter方法是我們重寫的,並且在其實現中並沒有編寫關於監聽屬性改變通知監聽的**,kvo依然可以起作用。這是為什麼呢?

我們都知道乙個類的例項方法存在於其類物件中,當乙個類的例項向例項方法傳送呼叫訊息時候,會通過類例項的isa指標去其類物件中找到其對應的例項方法執行。setter方法就存在於類物件中。

我們通過runtime的object_getclass()直接利用例項物件的isa指標查詢例項的類物件。

這裡之所以使用runtime獲取類物件而不使用訊息傳送機制,是因為class是通過訊息傳送查詢到class方法,在class方法中返回的類物件,而class方法可能被重寫。

通過上圖我們可以看出,使用kvo監聽的屬性的isa指向的類物件已經不是person了,而是乙個繼承自person的乙個新的類nskvonotifying_person,我們並沒有建立過這個類,它是objc的runtime動態生成的。

nskvonotifying_person重寫了父類的setage:classdealloc方法,並且新增了乙個_isk***方法。

我們可以看出在為person例項新增observer之前和之後的setage:方法的實現發生了變化,之前是直接呼叫類物件中儲存的例項方法,新增之後呼叫了foundation框架中_nssetintvalueandnotify函式。

之所以是_nsset*intvalue*andnotify是因為age屬性我們定義的是int型別,若是其他型別則會相應更改

_nssetintvalueandnotify方法中,會呼叫willchangevalueforkey,然後呼叫父類的setage方法,再呼叫didchangevalueforkey方法。在didchangevalueforkey中通知屬性改變,從而使得observevalueforkeypath得到訊息。

在我們獲取person例項的類物件的時候,我們發現使用runtime的object_getclass和使用訊息傳送機制[_person class]得到的結果不一樣,這是因為nskvonotifying_person重寫了class方法的實現,在實現中呼叫了[super class],而nskvonotifying_person又是person的子類,所以獲取到的person。

由於runtime在例項物件新增了kvo之後動態建立了類和一些物件,所以可能會在dealloc中**這些資源。

_isk*** 應該是會返回乙個bool型別的值,表示是否使用了kvo。

通過上面我們可以得知,kvo的實現主要是因為在setter方法中呼叫_nssetintvalueandnotify,而它呼叫willchangevalueforkey,然後呼叫父類的setage方法,再呼叫didchangevalueforkey方法,didchangevalueforkey告訴observevalueforkeypath屬性改變。所以我們可以通過實現will和did方法手動出發kvo。

通過上面原理我們可以知道,kvo主要是通過重寫setter方法實現的,而成員變數並不會實現setter方法,所以成員變數的改變並不會觸發kvo。

ObjC中Category的原理簡析

objective c類別也叫分類,是一種不需要繼承即可給類新增方法的語法技術。通常我們是用category為乙個類新增一些方法。我們可以直接用類似物件對方法呼叫的樣子直接對category中的方法進行呼叫。比如下面的例子,為person person類定義在.h和.m檔案中了,沒有給出 類定義了乙...

編譯原理中要點簡析

一 文法 0型文法又叫短文法,其能力相當於圖靈機。滿足a b中a包含非終結符 1型文法又叫上下文有關文法,其能力相當於線性有界自動機。滿足 b a a 空除外 2型文法又叫上下文無關文法,其能力相當於下推自動機。滿足1型文法的同時要求a是非終結符 對比0型文法 3型文法又叫正規文法,其能力相當於有限...

jQuery原理簡析

jquery原理簡析 function selector,context function jquery selector,context if typeof selector function 我們想要 selector 時就獲得乙個元素,且裡面有一些方法。這些方法要繫結在原型prototype上...