全稱是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...