KVO的用法spa
KVO也就是key-value-observing(即鍵值觀察),利用一個key來找到某個屬性並監聽其值得改變。用法以下:指針
//讓對象b監聽對象a的name屬性 //options屬性能夠選擇是哪一個 /* NSKeyValueObservingOptionNew =0x01, 新值 * NSKeyValueObservingOptionOld =0x02, 舊值 */ [a addObserver:b forKeyPath:@"name"options:kNilOptionscontext:nil]; a.name = @"zzz"; #pragma mark - 實現KVO回調方法 /* * 當對象的屬性發生改變會調用該方法 * @param keyPath 監聽的屬性 * @param object 監聽的對象 * @param change 新值和舊值 * @param context 額外的數據 */ - (void)observeValueForKeyPath:(NSString *)keyPathofObject:(id)objectchange:(NSDictionary<NSString *,id>*)change context:(void *)context{ NSLog(@"%@的值改變了,",keyPath); NSLog(@"change:%@", change); } //最後不要忘記了,去移除observer - (void)dealloc{ [a removeObserver:b forKeyPath:@"name"]; }
被觀察的對象Target(重寫setter/getter方法)
Target.hcode
@interface Target : NSObject { int age; } // for manual KVO - age- (int) age; - (void) setAge:(int)theAge; @end
Target.mserver
@implementation Target - (id) init{ self = [super init]; if (nil != self) { age = 10; } return self; } // for manual KVO - age - (int) age{ return age; } - (void) setAge:(int)theAge{ [self willChangeValueForKey:@"age"]; age = theAge; [self didChangeValueForKey:@"age"]; } + (BOOL) automaticallyNotifiesObserversForKey:(NSString *)key { if ([key isEqualToString:@"age"]) { return NO; } return [super automaticallyNotifiesObserversForKey:key]; } @end
首先,須要手動實現屬性的 setter 方法,並在設置操做的先後分別調用 willChangeValueForKey: 和 didChangeValueForKey方法,這兩個方法用於通知系統該 key 的屬性值即將和已經變動了;
其次,要實現類方法 automaticallyNotifiesObserversForKey,並在其中設置對該 key 不自動發送通知(返回 NO 便可)。這裏要注意,對其它非手動實現的 key,要轉交給 super 來處理。對象
KVO的實現是基於runtime運行時的,下面就來詳細介紹一下原理:仍是這張圖:blog
KVO與Notification之間的區別:ip
notification是須要一個發送notification的對象,通常是notificationCenter,來通知觀察者。資源
KVO是直接通知到觀察對象,而且邏輯很是清晰,實現步驟簡單。rem