KVC-KVO(キーボードコード-キー値観察)
KVC-KVO(キーボードコード-キー値観察)
KVC (key-value-coding)
メソッドのリスト
objc
// key
- (id)valueForKey:(NSString *)key;
//
- (void)setValue:(id)value forKey:(NSString *)key;
- (id)valueForKeyPath:(NSString *)keyPath;
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;
まずクラスを作成します
objc
@interface Student : NSObjec
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *sex;
@property (nonatomic, strong) NSString *code;
@property (nonatomic, assign) CGPoint position;
@end
私たちの以前の賦課方法では、私たちは必ずそうします.
objc
Student *stu = [[Student alloc] init];
//
stu.name = @"zhangsan";
stu.sex = @"male";
KVC方式を使用すれば、以下のコードを使用できます.
objc
//
[stu setValue:@"zhangsan" forKey:@"name"];
[stu setValue:@"name" forKey:@"sex"];
この2つの方式はここで等価といえるが,設定値に対応するkeyが属性リストに存在しない場合,クラッシュ現象が存在し,クラッシュ情報は以下のようになることに注意する.
[stu setValue:@"helo" forKey:@"phone"];
reason: '[0x100206af0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key phone.'
したがって、KVCを使用するにはkeyが属性リストに存在することに注意してください.
次に別の状況を見てみましょう.もしこの学生が先生を持っていたら、彼は先生の対応する値を設定したいと思っています.KVCを利用してどのように実現すればいいですか.
@interface Teacher : NSObject
@property (nonatomic, assign) CGPoint position; //
@property (nonatomic, strong) NSString *name; //
@end
そして私たちは学生に先生の属性を追加しました
objc
@property (nonatomic, strong) Teacher *teacher;
```
最後にmain関数で
```objc
Teacher *teacher = [[Teacher alloc] init];
//
stu.teacher = teacher;
//
stu.teacher.name = @"Jone";
// KVC, + +
[stu setValue:@"Mary" forKeyPath:@"teacher.name"];
//
NSLog(@"%@", stu.teacher.name);
```
KVO (key-value-observe)
いくつかの属性の変更を監視し、対応する操作を実行する必要がある場合があります.次に、学生が先生の位置が変更された場合、対応する操作をシミュレーションします.
同様に学生クラスにメソッドを追加します
```objc
#import "Student.h"
@implementation Student
- (void)watchTeacherPositionChanged
{
//
// 1:
// 2:
// 3:
// 4: nil NULL
[self addObserver:self
forKeyPath:@"teacher.position"
options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
context:@"position"];
}
Student.m
``objc
// ,
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
// change
if ([keyPath isEqualToString:@"teacher.position"]) {
NSValue * point = change[@"new"];
CGPoint newPoint = [point pointValue];
if (newPoint.x == self.position.x && newPoint.y == self.position.y) {
NSLog(@"%@ : , QQ", self.name);
} else {
NSLog(@"%@ : , , !", self.name);
}
}
}
そしてdeallocメソッドで
```objc
- (void)dealloc
{
//
[self removeObserver:self forKeyPath:@"teacher.position"];
}
main
```objc
Student * stu1 = [[Student alloc] init];
stu1.name = @"lisi";
stu1.position = CGPointMake(1, 1);
Student * stu2 = [[Student alloc] init];
stu2.position = CGPointMake(4, 2);
stu2.name = @"zhangsan";
// KVC KVO
Teacher * teacher = [[Teacher alloc] init];
stu1.teacher = teacher;
stu2.teacher = teacher;
// KVO
[stu1 watchTeacherPositionChanged];
[stu2 watchTeacherPositionChanged];
teacher.position = CGPointMake(1, 1);
teacher.position = CGPointMake(1, 2);
teacher.position = CGPointMake(4, 2);