KVO原理與手動(dòng)調(diào)用

KVO原理與手動(dòng)調(diào)用

一、KVO

KVO 是 Objective-C 對(duì)觀察者模式(Observer Pattern)的實(shí)現(xiàn)。當(dāng)被觀察對(duì)象的某個(gè)屬性發(fā)生更改時(shí),觀察者對(duì)象會(huì)獲得通知。

二、KVO實(shí)現(xiàn)原理

  • KVO是基于runtime機(jī)制實(shí)現(xiàn)的。
//創(chuàng)建Person對(duì)象,添加work屬性
@interface Person : NSObject
@property(nonatomic,copy) NSString * work;
@end

當(dāng)某個(gè)類(lèi)(Person)的屬性(work)對(duì)象第一次被觀察時(shí),系統(tǒng)就會(huì)在運(yùn)行期動(dòng)態(tài)地創(chuàng)建該類(lèi)的一個(gè)派生類(lèi)(NSKVONotifying_Person),在這個(gè)派生類(lèi)中重寫(xiě)基類(lèi)中任何被觀察屬性的setter 方法。派生類(lèi)在被重寫(xiě)的setter方法內(nèi)實(shí)現(xiàn)真正的通知機(jī)制

每個(gè)類(lèi)對(duì)象中都有一個(gè)isa指針指向當(dāng)前類(lèi),當(dāng)一個(gè)類(lèi)對(duì)象的第一次被觀察,那么系統(tǒng)會(huì)偷偷將isa指針指向動(dòng)態(tài)生成的派生類(lèi),從而在給被監(jiān)控屬性賦值時(shí)執(zhí)行的是派生類(lèi)的setter方法。
鍵值觀察通知依賴(lài)于NSObject 的兩個(gè)方法: willChangeValueForKey: 和 didChangevlueForKey:;在一個(gè)被觀察屬性發(fā)生改變之前, willChangeValueForKey:一定會(huì)被調(diào)用,這就 會(huì)記錄舊的值。而當(dāng)改變發(fā)生后,didChangeValueForKey:會(huì)被調(diào)用,繼而observeValueForKey:ofObject:change:context: 也會(huì)被調(diào)用。
派生類(lèi)中setter方法調(diào)用如下(偽代碼):

@implementation NSKVONotifying_Person
-(void)setWork:(NSString *)work{
    [self willChangeValueForKey:@"work"];
    NSLog(@"派生類(lèi)work");
    [self didChangeValueForKey:@"work"];
}
@end

三、手動(dòng)調(diào)用KVO

在Person類(lèi)中添加類(lèi)方法:

+(BOOL)automaticallyNotifiesObserversOfWork{
    return NO;
}

在觀察Person類(lèi)work屬性被觀察時(shí)的變化:


上述方法返回NO,則組織自動(dòng)調(diào)用鍵值觀察方法,在Person work setter方法里手動(dòng)調(diào)用:

-(void)setWork:(NSString *)work{
    if (_work == work) {
        return;
    }
    [self willChangeValueForKey:@"work"];
    _work = work;
    [self didChangeValueForKey:@"work"];
}

測(cè)試結(jié)果:


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

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

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