7.11 KVC和KVO
KVC
定义:键值编码
-
使用
//1.直接存键值 [p1 setValue:@"lisi"forKey:@"name"]; //2.通过path存键值 [p1 setValue:@"随便"forKeyPath:@"book.bookName"]; //3.字典转模型 NSDictionary *dict =@{@"name":@"wangwu",@"age":@"40"}; [p1 setValuesForKeysWithDictionary:dict]; //kvc 和数组 Person *p2 = [[Personalloc] init]; p2.name = @"yellow Mokey"; Person *p3 = [[Personalloc] init]; p3.name = @"red dog"; Person *p4 = [[Personalloc] init]; p4.name =@"green chicken"; NSArray *array = @[p2,p3,p4]; // 把三个对象中的name 取出来 NSArray *nameArray = [array valueForKeyPath:@"name"]; NSLog(@"%@",nameArray);
-
赋值过程
-
取值过程
面试题
- 通过KVC修改属性会触发KVO么?
- 会触发KVO
KVO
- 定义:键值监听
#import "MJPerson.h" @interface ViewController () @property (strong, nonatomic) MJPerson *person1; @property (strong, nonatomic) MJPerson *person2; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.person1 = [[MJPerson alloc] init]; self.person1.age = 1; self.person1.height = 11; // 给person1对象添加KVO监听 NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld; [self.person1 addObserver:self forKeyPath:@"age" options:options context:@"123"]; [self.person1 addObserver:self forKeyPath:@"height" options:options context:@"456"]; } - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { self.person1.age = 20; self.person1.height = 30; } - (void)dealloc { [self.person1 removeObserver:self forKeyPath:@"age"]; [self.person1 removeObserver:self forKeyPath:@"height"]; } // 当监听对象的属性值发生改变时,就会调用 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context { NSLog(@"监听到%@的%@属性值改变了 - %@ - %@", object, keyPath, change, context); }
面试题
- iOS用什么方式实现对一个对象的KVO?(KVO的本质是什么?)
- 利用RuntimeAPI动态生成一个子类,并且让instance对象的isa指向这个全新的子类(NSKVONotifying_xxx)
- 当修改instance对象的属性时,会调用Foundation的_NSSetXXXValueAndNotify函数
- willChangeValueForKey:
- 父类原来的setter
- didChangeValueForKey:
- 内部会触发监听器(Oberser)的监听方法( observeValueForKeyPath:ofObject:change:context:)
- 如何手动触发KVO?
- 手动调用willChangeValueForKey:和didChangeValueForKey:
[self.person1 willChangeValueForKey:@"age"]; [self.person1 didChangeValueForKey:@"age"];
- 手动调用willChangeValueForKey:和didChangeValueForKey:
- 直接修改成员变量会触发KVO么?
- 不会触发KVO