底層實現: 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"];