(iOS)KVO 的實現原理

Perfect_Dream發表於2017-12-20

概述

KVO,即:Key-Value Observing,它提供一種機制,當指定的物件的屬性被修改後,則其觀察者就會接受到通知。簡單的說就是每次指定的被觀察的物件的屬性被修改後,KVO就會自動通知相應的觀察者了。

KVO其實也是“觀察者”設計模式的一種應用。這種模式有利於兩個類間的解耦合,尤其是對於 業務邏輯與檢視控制 這兩個功能的解耦合。

KVO 的具體使用

 KVO是監聽物件的屬性值的改變的
 @param self.person 被檢測的物件
 @param self  檢測的物件
 @param @"name"  要監控的屬性
 @param options:  設定通知型別 
 */
 [self.person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];

//被檢查物件的值發生改變會呼叫該方法,這個方法屬於 NSObject 類的,任何物件都可以作為觀察者,
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
    NSLog(@"監聽到了%@的%@屬性發生了改變", object, keyPath);
    NSLog(@"%@", change);
}
複製程式碼

KVO 的實現原理

KVO 是基於執行時實現的

isa Class   NSKVONotifying_Person   0x000001a12de2f545
複製程式碼

上述例子中,當 person.name 的值改變時, person物件的 isa 指標會指向 NSKVONotifying_Person,意味著,在程式執行時,會動態生成一個 NSKVONotifying_Person 類,該類繼承於 Person,而且該類中也有個 -setName: 方法,方法中在設定 name 的同時實現了:

- (void)setName:(NSString *)name
{
    [super setName:name];

    // 這兩個方法底層會呼叫observer的- (void)observeValueForKeyPath: ofObject: change: context:這個方法
    [self willChangeValueForKey:@"name"];
    [self didChangeValueForKey:@"name"];
}
複製程式碼

本文轉載自原文



有志者、事竟成,破釜沉舟,百二秦關終屬楚;

苦心人、天不負,臥薪嚐膽,三千越甲可吞吳.

相關文章