Edited at

キー値監視(KVO)を理解する

More than 5 years have passed since last update.

キー値監視(KVO)とは、あるオブジェクトのプロパティの値が変更されたことを別のオブジェクトに

伝える仕組みのこと。

説明のため、監視されるオブジェクトfoo(Fooクラスのインスタンスfooとする)

と監視するオブジェクトbar(Barクラスのインスタンスをbarとする)を想定する。

fooオブジェクトはhogeというプロパティを持っておりこの値が変更されると

barオブジェクトに通知される。という状態をKVOを用いて実現する。

やることは2つ

1.監視オブジェクトの登録と監視キー(プロパティ)の登録

 ->具体的にはaddObserver:forKeyPath:options:を用いて以下のように登録する。

[foo addObserver:bar forKeyPath:@"hoge" options:NSKeyValueObservingOptionNew context:NULL];

2.監視してる側で変更通知を受けれるようにする。

 ->具体的にはbarクラスでobserveValueForKeyPath:ofObject:change:context:をオーバーライド

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context

{

NSLog(@"hoge property changed!");

}


やることは以上。監視プロパティを編集すると通知を受けることができる。

参考までに検証に用いたコードを以下に置きます。


main.m


#import <Foundation/Foundation.h>

@interface Foo:NSObject
@property NSNumber* hoge;
@end

@implementation Foo
@end

@interface Bar:NSObject
@end

@implementation Bar
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
NSLog(@"hoge property changed!");
}
@end

int main()
{
Foo* foo = [[Foo alloc] init];
Bar* bar = [[Bar alloc] init];

[foo addObserver:bar forKeyPath:@"hoge" options:NSKeyValueObservingOptionNew context:NULL];

foo.hoge = @1;
[foo removeObserver:bar forKeyPath:@"hoge"];

return 0;
}