KVO用法簡介及原理

KVO簡介

KVO全稱Key-Value Observing(鍵值監(jiān)聽),當前對象某個屬性值發(fā)生改變時,監(jiān)聽該屬性值變化的對象可以接到通知。

KVO實現(xiàn)原理

通過OC強大的Runtime運行時機制實現(xiàn)的。當?shù)谝淮斡^察當前對象時,Runtime會創(chuàng)建一個當前類的子類。在這個子類中,它會重寫所有被觀察的key,然后將對象的isa指針指向新創(chuàng)建的子類。所以當前對象神奇的變成了新的子類的實例。這些被重寫的方法中添加了調(diào)用通知觀察者的方法的代碼。當一個對象的一個屬性改變時,會觸發(fā)setKey方法,但這個方法被重寫了,并且在內(nèi)部添加了發(fā)送通知機制。

簡單使用

//在Person.h中增加一個屬性age
@interface Person : NSObject

@property (nonatomic, assign) NSInteger age;

@end

// 在Dog.m中添加KVO監(jiān)聽方法observeValueForKeyPath:ofObject:change:context:
@implementation Dog

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
    NSLog(@"%@監(jiān)聽到了%@對象的%@屬性的值改變了:%@",self ,object ,keyPath ,change);
}

@end
@interface ViewController ()

@property (nonatomic, strong) Person *person;
@property (nonatomic, strong) Dog *dog;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.person = [[Person alloc] init];
    self.dog = [[Dog alloc] init];
    
    self.person.age = 10;
    // self.dog 監(jiān)聽self.person的age屬性
    [self.person addObserver:self.dog forKeyPath:@"age" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    self.person.age = 50;
}

@end

我們運行程序,然后點擊空白屏幕,就會看到如下輸出,說明我們的確實已經(jīng)能夠使用KVO監(jiān)聽屬性變化了。

0.png

然后我們通過打斷點的方式,會看到在調(diào)用addObserver:forKeyPath:options:context:方法前后Person所屬類是不同的。

添加觀察器之前:

1.png

添加觀察器之后:

2.png

通過前后對比,我們發(fā)現(xiàn)當person對象被監(jiān)聽后,系統(tǒng)在運行時動態(tài)創(chuàng)建了一個繼承自Person的子類NSKVONOtifying_Person類。然后KVO會在這個派生類中,重寫基類中任何被觀察屬性的setter方法,在setter方法中實現(xiàn)真正的通知機制。

KVO是一個很強大的工具,有時候過于強大了,尤其是有了自動觸發(fā)通知機制?,F(xiàn)在我們知道了它的工作原理,知道使用它會在運行時創(chuàng)建一個新的類,所以性能會有一定影響,因此除非非要監(jiān)聽某個屬性值的變化時候才使用它。這些知識或許能幫助你更好地使用它,或在它出錯時更方便調(diào)試。

以上內(nèi)容摘錄借鑒于:KVO實現(xiàn)原理

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前言 Key-Value-Observer,它來源于觀察者模式, 其基本思想(copy于某度)是一個目標對象管理所...
    CholMay閱讀 3,530評論 6 18
  • 一、概述 KVO,即:Key-Value Observing,它提供一種機制,當指定的對象的屬性被修改后,則其觀察...
    DeerRun閱讀 10,199評論 11 33
  • 上半年有段時間做了一個項目,項目中聊天界面用到了音頻播放,涉及到進度條,當時做android時候處理的不太好,由于...
    DaZenD閱讀 3,098評論 0 26
  • KVC 什么是 KVC KVC 是 Key-Value-Coding 的簡稱。 KVC 是一種可以直接通過字符串的...
    LeeJay閱讀 2,258評論 6 41
  • 本文結(jié)構(gòu)如下: Why? (為什么要用KVO) What? (KVO是什么) How? ( KVO怎么用) Mo...
    等開會閱讀 1,729評論 1 21

友情鏈接更多精彩內(nèi)容