KVC KVOについて

3124 ワード

KVC


NSKeyValueCodingプロトコルキー値符号化(key-value)、指定したkeyは対応するvalueを取得する.クラス内のプライベート変数は、Setterメソッド、Getterメソッドで直接アクセスできません.しかし、KVCでアクセスできる.kvcのこの特性を利用して、システム内のいくつかのプライベート変数にアクセスすることができます.
valueForKey: setValue:@""forKey:@"keypath"; keyを直接設定できます.keyPathは属性とメンバー変数の名前です.Key:現在のオブジェクトのプロパティにのみアクセスできますKeyPath:演算子を使用して、プロパティに階層的にアクセスできます.
<1> .構文とkvcはアクセスメソッドを実現したクラスでは、ポイント構文とKVCアクセスオブジェクトの使用は実際には大きく異なり、両者は任意に混用することができる.
<2>kvcにおける数値とデータ構造
NSNumberは一般的な基礎データ型のオブジェクトである.NSValueは主にいくつかの構造体型のデータとカスタムのデータ構造タイプである.
では、keyPathとして属性名を指定します.システムは、対応するメンバー変数と属性を検索するのにどのように役立ちますか?
①ブール値のみに有効な-、-is、または-getのアクセサメソッドが存在するかどうかを確認し、可能であればこれらのメソッドで値を返す.-set:というメソッドがあるかどうかを確認し、設定値に使用します.-getと-set:メソッドでは、大文字のKey文字列の最初のアルファベットをCocoaのメソッド名と一致させます.
②上記の方法が使用できない場合、検査名は-、-is(ブール値のみ有効)、-getと-set:メソッド;③アクセサメソッドが見つからない場合は、インスタンス変数に直接アクセスしてみてください.インスタンス変数は、名前:または;
④見つからない場合は、valueForUndefinedKey:およびsetValue:forUndefinedKey:メソッドを呼び出します.これらの方法のデフォルト実装は例外を投げ出しており,必要に応じて書き換えることができる.
  valueForUndefinedKey:

/* Given that an invocation of -valueForKey: would be unable to get a keyed value using its default access mechanism, return the keyed value using some other mechanism. The default implementation of this method raises an NSUndefinedKeyException. You can override it to handle properties that are dynamically defined at run-time.
*/


NSDictionary objectForkeyの場合:valueForKeyと区別
一般的にkeyは任意の文字列の組合せであってもよく、keyが@記号で始まる場合、valueForKey:objectForKeyと同等であり、@で始まる場合、keyの中の@を除いて残りの部分をkeyとして実行する[super valueForKey:].
NSDictionary *dict = [NSDictionary dictionaryWithObject:@"theValue" forKey:@"@theKey"];
NSString *value1 = [dict objectForKey:@"@theKey"];
NSString *value2 = [dict valueForKey:@"@theKey"];

value1  ok, value2 crash 
NSUnknownKeyException’, reason: ‘[<__nscfdictionary> valueForUndefinedKey:]: 
  KVC   property  。 @"@theKey" @"theKey", valueForUndefinedKey  ;

KVO


NSObject(NSKeyValueObserving)
  • 登録傍受
  • 傍受イベント処理
  • リスニングをキャンセル
  • クラスのオブジェクトが初めて観察されると、システムは実行中にクラスの派生クラスを動的に作成し、この派生クラスでベースクラスの観察された属性のsetterメソッドを書き換える.派生クラスは、キー値観察を手動で実現するように、書き換えられたsetterメソッドで真の通知メカニズムを実現する.これは、設定プロパティに基づいてsetterメソッドが呼び出され、次の2つの方法で実現されます.
  • (void)willChangeValueForKey:(NSString *)key
  • (void)didChangeValueForKey:(NSString *)key;
  • didChangeValueForKey  :
    - (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary *)change context:(nullable void *)context;
    
     
    - (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
    - (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath context:(nullable void *)context NS_AVAILABLE(10_7, 5_0);
    

    KVOとNSNotificationCenterアップルは、オブジェクトのアドレスを1つだけ保存し、破棄時にnilに設定していないことを実装しています.したがってaddObserverの後、remove操作が必要です.