日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

轻量级KVO ——》 KVO 管理 observeValueForKeyPath

發布時間:2024/9/30 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 轻量级KVO ——》 KVO 管理 observeValueForKeyPath 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【轉】http://joeyio.com/2013/10/21/lightweight_kvo/

在這篇文章中,我會實現一個自己用的簡單KVO類,我認為KVO非常棒,然而對于我大部分的使用場景來說,有這兩個問題:
1. 我不喜歡在observeValueForKeyPath:ofObject:change:context:方法里通過keyPath值來做調度,當Observe比較多的對象時,會使得代碼變得雜亂和迷惑。 2. 必須手動的來注冊和刪除一個觀察者,如果能自動做就好了。

So,我們開始這個實現。這個技巧我第一次是在THObserversAndBinders項目中見到,本篇內容也僅僅描述了一下里面的做法,同時做了簡化。

首先,我們定義一下我們的這個類,我們這個幫助類的類名是Observer:

@interface Observer : NSObject + (instancetype)observerWithObject:(id)objectkeyPath:(NSString*)keyPathtarget:(id)targetselector:(SEL)selector; @end

Observer類的這個類方法有四個參數,每個參數都是自解釋的,我選擇使用target/action模式,當然也可以使用block,但是那樣的話需要做weakSelf/strongSelf的轉換,你懂的,通常來說分來來做比較好。

我們做的是在初始化方法中設置KVO,并在dealloc方法中移除。這意味著一旦Observer對象被retain,我們就有了一個觀察者,下面這段代碼是從我的一個ViewCOntroller中拿來的:

self.usernameObserver = [Observer observerWithObject:self.userkeyPath:@"name"target:selfselector:@selector(usernameChanged)];

把這個Observer對象作為一個屬性放在ViewController中來保證被retain,一旦我們的Viewcontroller被釋放,就會設置它為nil,observer就停止觀察了。

在這個實現中,使用一個weak引用指向被觀察對象和觀察者(target)是很重要的,如果兩個中的其中一個是nil,我們就停止向觀察者發送消息。

@interface Observer () @property (nonatomic, weak) id target; @property (nonatomic) SEL selector; @property (nonatomic, weak) id observedObject; @property (nonatomic, copy) NSString* keyPath; @end

初始化器里設置KVO通知,使用self作為context,如果我們會有一個子類也添加類似的觀察者時就很有必要了。

- (id)initWithObject:(id)object keyPath:(NSString*)keyPath target:(id)target selector:(SEL)selector {if (self) {self.target = target;self.selector = selector;self.observedObject = object;self.keyPath = keyPath;[object addObserver:self forKeyPath:keyPath options:0 context:self];}return self; }

一旦被觀察者發生變化,我們就通知觀察者(target),如果它還存在的話:

- (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context { if (context == self) {id strongTarget = self.target;if ([strongTarget respondsToSelector:self.selector]) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks"[strongTarget performSelector:self.selector]; #pragma clang diagnostic pop} } }

最后在dealloc方法中移除觀察者對象:

- (void)dealloc {id strongObservedObject = self.observedObject;if (strongObservedObject) {[strongObservedObject removeObserver:self forKeyPath:self.keyPath];} }

這就是全部內容了。還有很多可以擴展的地方,比如增加block的支持,或者我比較喜歡的trick:再增加愛一個方便的構造方法用來第一次直接調用action。然而,我想的是展現出這個技術的核心部分,你可以根據自己的需求來調整它。

這個技術的優點是在使用KVO的時候不需要記住太多東西,僅僅retain住Observer對象,然后在完成的試試置為nil即可,剩下的會自動完成。

原文作者是Chris Eidhof,objc.io的創辦者
原文地址:Lightweight Key-Value Observing

總結

以上是生活随笔為你收集整理的轻量级KVO ——》 KVO 管理 observeValueForKeyPath的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。