IOSにおけるKVCとKVOの応用解析
4985 ワード
IOSにおけるKVCとKVOの応用解析
一、NSKeyValueCoding(KVC)
1、一例から導入する
KVCキー値符号化はObject−Cが我々に提供するメンバー変数に値を付与する方法である.その方法を検討する前に、小さな例を見てみましょう.
まず、データモデルモデルクラスを作成します.
//.h
#import <Foundation/Foundation.h>
@interface Model : NSObject
{
@public//
NSString * str;
}
@end
他のファイルではstrを割り当て、値を取る2つの方法があります.
Model * model = [[Model alloc]init];
model->str=@"312";//
[model setValue:@"321" forKey:@"str"];//kvc
NSLog(@"%@",model->str);//
NSLog(@"%@",[model valueForKey:@"str"]);//kvc
同様に,@propertyで宣言された変数に対してkvcを用いる効果と点構文,setter,getterメソッドを用いる効果は同じである.
2、KVC関連関数方法の詳細
上記の例を通して、KVCが何をしているのかを簡単に理解することができます.以下はいくつかの一般的な方法です.
+ (BOOL)accessInstanceVariablesDirectly;
この方法はスイッチのようなもので、デフォルトではYESで、KVC方式の付与をサポートしていることを示しています.サブクラスで書き換えることもできます.NOに戻ると、KVCを行うと異常が放出されます.
- (id)valueForKey:(NSString *)key;
キーによる値の取得
- (void)setValue:(id)value forKey:(NSString *)key;
文字列キーでメンバー変数に値を割り当てる
- (BOOL)validateValue:(inout id *)ioValue forKey:(NSString *)inKey error:(out NSError **)outError;
システムのデフォルトの実装方法で、キー値が有効かどうかを検証します.
- (NSMutableArray *)mutableArrayValueForKey:(NSString *)key;
取得した値を可変配列に挿入
- (NSMutableOrderedSet *)mutableOrderedSetValueForKey:(NSString *)key NS_AVAILABLE(10_7, 5_0);
取得した値を可変秩序セットに挿入
- (NSMutableSet *)mutableSetValueForKey:(NSString *)key;
取得した値を可変コレクションに挿入
- (id)valueForKeyPath:(NSString *)keyPath;- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;
上記の2つの方法はそれぞれパス賦値と取値によって行われ、データ構造は地図に似ています.例えば、modelクラスにメンバー変数model 2があり、model 2クラスに文字列があり、以下のように値を賦値することができます.
//Model.h
#import "Model2.h"
@interface Model : NSObject
{
@public
NSString * str;
Model2 * model2;
}
//Model2.h
@interface Model2 : NSObject
{
@public
NSString * str2;
}
@end
//
Model * model = [[Model alloc]init];
Model2 * model2 = [[Model2 alloc]init];
model->model2=model2;
[model setValue:@"123" forKeyPath:@"model2.str2"];
NSLog(@"%@",[model valueForKeyPath:@"model2.str2"]);
- (NSMutableArray *)mutableArrayValueForKeyPath:(NSString *)keyPath;- (NSMutableOrderedSet *)mutableOrderedSetValueForKeyPath:(NSString *)keyPath NS_AVAILABLE(10_7, 5_0);- (NSMutableSet *)mutableSetValueForKeyPath:(NSString *)keyPath;
上の3つの方法は前と似ていますが、パスから値を取っただけです.
- (id)valueForUndefinedKey:(NSString *)key;
このメソッドは、実行時に作成されたように、事前に定義されていないメンバー変数の値を取得できます.次のメソッドは、定義されていないメンバー変数に値を付与します.
- (void)setValue:(id)value forUndefinedKey:(NSString *)key;
注:この2つのメソッドのデフォルトのインプリメンテーションは例外を放出し、サブクラスは書き直さなければ使用できません.
- (void)setNilValueForKey:(NSString *)key;
メンバー変数をnilに設定
- (NSDictionary *)dictionaryWithValuesForKeys:(NSArray *)keys;
キー値に基づいてキー値対辞書を取得
- (void)setValuesForKeysWithDictionary:(NSDictionary *)keyedValues;
辞書でメンバー変数の割り当てに同意し、よく使用されます.
二、NSKeyValueObservingCustomization(KVO)
KVOはメッセージ傍受メカニズムであり,ある量が変化したときにメッセージを傍受者に伝送できるため,伝達値,インタフェースの低結合などの論理に広く用いられている.KVOメカニズムの核心は以下の3つの方法である.
- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;
このメソッドを使用してリスナーを登録します.パラメータは次のように説明されます.
observer:リスナーオブジェクト
keyPath:リスニングのパラメータ
options:リスニングオプション
context:パラメータ転送
リスニングのオプションは次のように列挙されます.
typedef NS_OPTIONS(NSUInteger, NSKeyValueObservingOptions) {
NSKeyValueObservingOptionNew = 0x01,//
NSKeyValueObservingOptionOld = 0x02,//
NSKeyValueObservingOptionInitial ,//
NSKeyValueObservingOptionPrior//
};
//
- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath context:(void *)context ;- (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;
この2つの方法は、リスナーを削除するために使用されます.
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;
この方法は,オブジェクトデータの変更時のコールバックを傍受する方法であり,changeは辞書であり,辞書には傍受のオプションに応じて異なる値(新しいまたは古い)が格納される.contextは伝達されるパラメータです.
コードの例:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
model = [[Model alloc]init];
//
[model addObserver:self forKeyPath:@"str" options:NSKeyValueObservingOptionNew context:@"321"];
[model setValue:@"qw" forKey:@"str"];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
if ([keyPath isEqualToString:@"str"]) {
NSLog(@"%@",context);
}
}
学習利用へようこそ