底层实现: 1.动态建立对象的NSKVONotifing_类,作KVO前端
2.修改当前对象的isa指针指向NSKVONotifying_Personandroid
3.只要调用对象的set,NSKVONotifying_Person的set方法数组
4.重写NSKVONotifying_Person的set方法 1.[super set:] 2.通知观察者,告诉你属性改变编码
//就会调用经过区判断有没有调用一个对象的setter方法spa
验证: _p->_age ++;
- (void)viewDidLoad { [super viewDidLoad]; self.p = [[Person alloc] init]; self.p.age = 20; //KVO属性监听 //监控某个属性的值改变就会调用 [self.p addObserver:self forKeyPath:@"age" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil]; } -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context { /* * keyPath 属性名(哪一个属性被改) * object 哪一个对象的属性被改了 * change 属性的修改状况 * context void * == id 传值 */ } //和通知同样,须要释放 -(void)dealloc { [self.p removeObserver:self forKeyPath:@"age"]; }
概念:指针
KVC(键值编码)是一种间接访问对象是实例变量的机制,该机制能够不经过存储方法就能够访问对象的实例变量code
1,KVC能够设置改变系统控件只读属性server
//UITabBar的属性是readOnly,咱们不能直接自定义控件和改变系统taBar WBUITabBar *tabbar = [[WBUITabBar alloc] init]; [self setValue:tabbar forKeyPath:@"tabBar"];
2,keyPath和key的区别对象
//简单状况下,是没有区别的 [p.dog setValue:@"wangcai" forKey:@"name"]; [p.dog setValue:@"larry" forKeyPath:@"name"]; //复杂状况下,key不能读取下一层属性 [p setValue:@"hashiqi" forKeyPath:@"dog.name"]; [p setValue:@"hashiqi" forKey:@"dog.name"]; // 写法错误XXXXXXXXXXXXX forKeyPath包含了forKey的功能,之后使用forKeyPath就能够了 forKeyPath中能够利用.运算符, 就能够一层一层往下查找对象的属性
3,利用KVC快速将属性值添加到数组开发
Person *p = [[Person alloc] init]; Book *book1 = [[Book alloc] init]; book1.name = @"5分钟突破iOS开发"; book1.price = 10.5; Book *book2 = [[Book alloc] init]; book2.name = @"5分钟突破android开发"; book2.price = 18.5; Book *book3 = [[Book alloc] init]; book3.name = @"5分钟突破前端开发"; book3.price = 20.5; Book *book4 = [[Book alloc] init]; book4.name = @"5分钟突破PHP开发"; book4.price = 10.5; p.books = @[book1, book2, book3, book4]; //普通方法 // 得到全部的书名(将全部的书名放到一个数组中) NSMutableArray *names = [NSMutableArray array]; for (Book *book in p.books) { [names addObject:book.name]; } //高效方法 // 取出books数组中每个元素的name属性值,放到一个新的数组中返回 NSArray *names = [p valueForKeyPath:@"books.name"]; NSLog(@"%@", names);
4,利用KVC得到的数值进行简单运算
NSNumber *avgNumber = [p valueForKeyPath:@"books.@avg.price"]; NSNumber *sumNumber = [p valueForKeyPath:@"books.@sum.price"];