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);