iOS KVO的實現原理

2021-07-11 09:50:12 字數 2639 閱讀 6042

全稱是key-value observing,翻譯成鍵值觀察。提供了一種當其它物件屬性被修改的時候能通知當前物件的機制。再mvc大行其道的cocoa中,kvo機制很適合實現model和controller類之間的通訊。

鍵值編碼(kvc)和鍵值觀察(kvo)是根據isa-swizzling技術來實現的,主要依據runtime的強大動態能力。

當某個類的物件第一次被觀察時,

系統就會在執行期動態地建立該類的乙個派生類,在這個派生類中重寫基類中任何被觀察屬性的 setter方法。派生類在被重寫的 setter 方法中實現真正的通知機制;

系統將這個物件的 isa指標指向這個新誕生的派生類,因此這個物件就成為該派生類的物件了,因而在該物件上對 setter 的呼叫就會呼叫重寫的 setter,從而啟用鍵值通知機制。此外,派生類還重寫了 dealloc 方法來釋放資源。

新的派生類nskvonotifying_person類會重寫以下方法:

增加了監聽的屬性對應的set方法,class,dealloc,_isk***。

//重寫set方法

新類會重寫對應的set方法,是為了在set方法中增加另外兩個方法的呼叫:

1  

-(void)willchangevalueforkey:(nsstring

*)key2 -

(void)didchangevalueforkey:(nsstring

*)key

其中,didchangevalueforkey:方法負責呼叫下面這這監聽:

1  

-(void)observevalueforkeypath:(nsstring

*)keypath

2 ofobject:(id)object

3 change:(nsdictionary

*)change

4 context:(void

*)context

方法,這就是kvo實現的原理了!

如果沒有任何的訪問器方法,-setvalue:forkey方法會直接呼叫:

1  

-(void)willchangevalueforkey:(nsstring

*)key2 -

(void)didchangevalueforkey:(nsstring

*)key

如果在沒有使用鍵值編碼且沒有使用適當命名的訪問器方法的時候,我們只需要顯示呼叫上述兩個方法,同樣可以使用kvo!

總結一下,想使用kvo有三種方法:

1)使用了kvc

使用了kvc,如果有訪問器方法,則執行時會在訪問器方法中呼叫will/didchangevalueforkey:方法;

沒用訪問器方法,執行時會在setvalue:forkey方法中呼叫will/didchangevalueforkey:方法。

2)有訪問器方法

執行時會重寫訪問器方法呼叫will/didchangevalueforkey:方法。

因此,直接呼叫訪問器方法改變屬性值時,kvo也能監聽到。

3)顯示呼叫will/didchangevalueforkey:方法。

總之,想使用kvo,只要有will/didchangevalueforkey:方法就可以了。

③_isk***

這個私有方法估計是用來標示該類是乙個 kvo機制聲稱的類。

@inte***ce

viewcontroller ()

@property (nonatomic,strong)lbperson*person;//必須設定成屬性,防止被銷毀,否則報錯

@end

@implementation viewcontroller

- (void)viewdidload

- (void)dealloc

//屬性只改變時會呼叫這個方法

- (void)observevalueforkeypath:(nsstring *)keypath ofobject:(id)object change:(nsdictionary

*)change context:(void *)context

-(void)downloadfile completionhandler:^(nsurlresponse*_nonnull response,nsurl* _nullable filepath,nserror * _nullableerror) ] resume];

//輸出進度

kvo新增觀察者

/*1.

誰觀察2.

觀察的key

3.選項

*/[progress addobserver:

self

forkeypath:

@"fractioncompleted"

options:nskeyvalueobservingoptionnewcontext:

nil];

}-(void)observevalueforkeypath:(nsstring *)keypath ofobject:(id)object change:(nsdictionary

*)change context:(void *)context

}

iOS KVO 實現原理

kvo 屬性觀察者 是觀察者模式的一種具體實現,主要通過觀察物件屬性值的變化,觸發對應的方法 下面學習下 kvo 的具體實現 和 底層實現原理 原生觀察者實現 1 為 狗 物件d新增乙個觀察者為自己,同時監聽物件d age年齡屬性的改變 dog d dog new p addobserver sel...

iOS KVO存在的坑

所有的設計模式最終目的都是乙個,就是要解耦。解耦 是指任何模組之間不存在硬關聯,都是可以對關聯進行修改與替換。這是提供系統的可擴充套件性和可維護性的基礎,降低模組 元件之間的耦合度是開發人員應該牢記的乙個程式設計準側。觀察者模式是一種行為型設計模式。行為型設計模式討論的是模組實體在執行過程中的行為模...

實現原理 Vuex的實現原理

你知道vuex如何工作的嗎?先來看下圖了解下 了解圖之後看來下 的實現原理吧 let vue class store this.mutations this.actions this.vm new vue const options if getters if mutations if action...