備忘録

開発でつまったところの備忘録.不定期に更新します.

キー値コーディング

キー値コーディングとはオブジェクトが持つ情報を表す文字列をキーとして用いて間接的にその値にアクセスする仕組みです。基本的にはアクセサメソッドか宣言プロパティ、またはインスタンス変数が存在していれば、その名前を文字列として指定してアクセス可能という機能です。

 

キー値コーディングに必要なメソッドは

- (id) valueForKey : (NSString *) key ;

プロパティを表す文字列keyに対応する値を返す

- (void) setValue : (id) value forKey : (NSString *) key ;

keyに対応するプロパティの値をvalueに設定する

の二つです。

 

プロパティへのアクセスは基本的にアクセサを用います。無い場合はインスタンス変数を見つけて返します。返り値がオブジェクトでない場合(int等)適宜オブジェクトでラップして返します。

 

辞書オブジェクトはプロトコルNSKeyValueCodingを備え、キー値コーディングに対応しています。

 

プロパティがオブジェクトの場合、それがさらにプロパティを持ち、そこにアクセスしたいとします。

そのとき

- (id) valueForKeyPath : @" firstObject . secondObject " ;

のように"."でつないでアクセスすることができます。この"."でつないだ文字列をキーパスと呼びます。

 

これらのように、あるプロパティに対してキー値コーディングを使ったアクセスができることをKVC準拠であるといいます。

 

あるオブジェクトのプロパティ変化したことを別のオブジェクトに伝える仕組みをキー値監視(KeyValueObserving : KVO)と呼びます。

キー値監視では監視対象となるオブジェクトに対して監視したいプロパティのキーパスと、監視元のオブジェクト(オブザーバ)を登録します。これは

- (void) addObserver : (NSObject *) anObserver forKeyPath : (NSString *) keyPath options : (NSKeyValueObservingOptions) options context : (void *) context ;

メソッドで設定できます。

レシーバ(監視対象)から見てkeyPathの場所にあるプロパティを監視することやオブザーバをレシーバに登録します。通知のメッセージには変化の内容を表す辞書データと、contextに表されるポインタが含められます。optionsで変化前のデータか変化後のデータかを設定できます。

 

このメソッドで監視を指定したプロパティに変化があるとオブザーバに対して次のメッセージが送られます。全てのオブザーバはこのメソッドを実装している必要があります。

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

 

あるプロパティの値が同じオブジェクトの別のプロパティの変更に伴って変化することはよくあります。そのような依存関係をクラス毎に登録しておいて、間接的に値が変化したプロパティについても通知メッセージを送ることができます。

+ (void) setKeys : (NSArray *) keys triggerChangeNotificationForDependentKey : (NSString *) dependentKey ;

このメソッドで、配列keysに格納されたどれかのキーに対応するプロパティに変化が会った場合に、自動的にdependentKeyのプロパティについても変化があったのと同じ動作が発生するように依存関係を設定できます。