KVO進階(二)

前言

這篇文章主要寫KVO的內(nèi)部通知

正文

先上代碼

0-0
0-1

經(jīng)測試,person.name = @"Jack"[person setValue:@"Jack" forKey:@"name"]均可觸發(fā)KVO,而[person changeName:@"Jack"]不能。前兩種方式會訪問setter,第三種直接訪問成員變量,可以猜測KVO內(nèi)部是在setter中觸發(fā)的。
Foundation/NSKeyValueObserving.h可以找到以下方法

- (void)willChangeValueForKey:(NSString *)key;
- (void)didChangeValueForKey:(NSString *)key;
+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key;

+(BOOL)automaticallyNotifiesObserversForKey:(NSString *)key控制是否自動發(fā)送通知,如果返回NO,KVO無法自動運作,需手動觸發(fā)。因為前兩個方法默認是在setter中實現(xiàn)的(用KVO做鍵值觀察后,系統(tǒng)會在運行時重寫被觀察對象屬性的setter),即:

- (void)setName:(NSString *)name {
    [self willChangeValueForKey:@"name"];
    _name = name;
    [self didChangeValueForKey:@"name"];
}

那么如果把這兩個方法移植到- (void)changeName:(NSString *)name中會怎樣?

- (void)changeName:(NSString *)name {
    [self willChangeValueForKey:@"name"];
    _name = name;
    [self didChangeValueForKey:@"name"];
}
運行結(jié)果

看吧,KVO又跑起來了。

再來看一下他們的調(diào)用順序

1-0

顯然和我們猜測的順序沒有出入,完全正確

這里重寫
+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key
沒有什么卵用,只是方便查看調(diào)用順序。因為auto這個方法只和setter相關,而現(xiàn)在是調(diào)用自定義方法并且內(nèi)部直接訪問成員變量。
至于內(nèi)部設置的那個name攔截,純屬為了娛樂??

自己出發(fā)KVO通知會生成中間類嗎?(關于中間類,且聽下回分解。。)當然會!

關于手動觸發(fā)的例子很多,比如主流三方框架SDWebImage中的SDWebImageDownloaderOperation.hMJRefesh中的UIScrollView+MJRefresh.h,有興趣可以看下源碼,這里不做解析。

如果兩次設置的值相同會怎樣?

2-0

WTF!相同的值干嘛還要監(jiān)聽?把代碼改進一下

+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key {
    if ([key isEqualToString:@"name"]) {
        return NO;
    }
    return [super automaticallyNotifiesObserversForKey:key];
}

- (void)setName:(NSString *)name {
    if ([_name isEqualToString:name]) {
        return;
    }
    [self willChangeValueForKey:@"name"];
    _name = name;
    [self didChangeValueForKey:@"name"];
}

再來看一下結(jié)果

3-0

多幾次嘗試,總會有意外的收獲。成文匆忙,有錯誤的地方還請指正、包涵。

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

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

  • 本篇會對KVO的實現(xiàn)進行探究,不涉及太多KVO的使用方法,但是會有一些使用時的思考。 一、使用上的疑問 1.key...
    奮拓達閱讀 565評論 0 2
  • 目錄:1.KVC用法;2.KVC和對象的setter、getter方法的區(qū)別;3.key和keyPath的區(qū)別;4...
    倫倫子_f7b3閱讀 685評論 0 1

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