1. KVC (Key value coding)
我們一般是通過調用set方法或屬性的點語法來直接更改對象的狀態,即對象的屬性值,比如[stu setAge:10];? stu.age = 9;
KVC,它是一種間接更改對象狀態的方式,其實現方法是使用字符串來描述對象需要更改的屬性。KVC中的基本調用包括valueForKey:和setValue:ForKey:,以字符串的形式向對象發送消息
2.valueForKey
使用valueForKey:獲取Student對象的name
NSString *name = [student valueForKey:@"name"];
valueForKey:首先查找以name或isName命名的getter方法,如果不存在getter方法,就在對象內部查找名為_name或name的實例變量
注意,下列語句是合法的
NSLog(@"age is %@", [student valueForKey:@"age"]);
NSLog中的%@輸出一個對象,但age是一個int值,而不是對象,為什么會合理呢?原因如下:
使用valueForKey:時,KVC會自動將標量值(int、float、struct等)翻入NSNumber或NSValue中包裝成一個對象,然后返回。因此,KVC有自動包裝功能。
3.批處理
KVC可以對對象進行批量更改
例如,同時獲取Student的age和name
NSArray *keys = [NSArray arrayWithObjects:@"name", @"age", nil];
NSDictionary *dict = [student dictionaryWithValuesForKeys:keys];
同時設置Student的age和name
NSArray *keys = [NSArray arrayWithObjects:@"name", @"age", nil];
NSArray *values = [NSArray arrayWithObjects:@"ZK", [NSNumber numberWithInt:16], nil];
NSDictionary *dict = [NSDictionary dictionaryWithObjects:values forKeys:keys];
[student setValuesForKeysWithDictionary:dict];
4.鍵路徑(key path)
除了通過鍵設置值外,KVC還支持鍵路徑,像文件系統路徑一樣,其實就是屬性鏈式訪問
比如,利用鍵路徑設置Student對象中Card對象的no
[student setValue:@"12345" forKeyPath:@"card.no"];
獲取Student對象中Card對象的no
[student valueForKeyPath:@"card.no"];
5.數組的整體操作
如果向一個NSArray請求一個key,KVC會查詢數組中的每個對象來查找這個key,然后將查詢結果打包到另一個數組中并返回
例如,Student里面有很多Book對象
獲取Student中所有Book的name
NSArray *names = [student.books valueForKeyPath:@"name"]; 或者
NSArray *names = [student valueForKeyPath:@"books.name"];
注意:不能在鍵路徑中為數組添加索引,比如@"books[0].name"
6.鍵路徑的運算符
在鍵路徑中,可以引用一些運算符來進行一些運算,例如獲取一組值的平均值、最小值、最大值或者總數
例如,計算Student中Book的總數
NSNumber *count = [student.books valueForKeyPath:@"@count"];? 或者
NSNumber *count = [student valueForKeyPath:@"books.@count"];
計算Student中所有Book的價錢(price)總和
NSNumber *sum = [student.books valueForKeyPath:@"@sum.price"]; 或者
NSNumber *sum = [student valueForKeyPath:@"books.@sum.price"];
找出Student中Book的所有不同價位(排除相同價位)
NSArray *prices = [student.books valueForKeyPath:@"@distinctUnionOfObjects.price"];
或者
NSArray *prices = [student valueForKeyPath:@"books.@distinctUnionOfObjects.price"];
7.KVO(key value observing)
KVO是一種非常重要的機制,它允許監聽對象的屬性的變化
注冊監聽器
-(void)addObserver:(NSObject *)anObserver forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context
anObserver :監聽器對象
keyPath :監聽的屬性
options :決定了當屬性改變時,要傳遞什么數據給監聽器
監聽器需要實現監聽方法
-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)objectchange:(NSDictionary *)change context:(void *)context
keyPath :監聽的屬性
object :誰的屬性改變了
change :屬性改變時傳遞過來的信息(取決于添加監聽器時的options參數)
移除監聽器
-(void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath