1. KVC (Key value coding)
我們一般是通過(guò)調(diào)用set方法或?qū)傩缘狞c(diǎn)語(yǔ)法來(lái)直接更改對(duì)象的狀態(tài),即對(duì)象的屬性值,比如[stu setAge:10];? stu.age = 9;
KVC下面,它是一種間接更改對(duì)象狀態(tài)的方式,其實(shí)現(xiàn)方法是使用字符串來(lái)描述對(duì)象需要更改的屬性。KVC中的基本調(diào)用包括valueForKey:和setValue:ForKey:叮姑,以字符串的形式向?qū)ο蟀l(fā)送消息
2.valueForKey
使用valueForKey:獲取Student對(duì)象的name
NSString *name = [student valueForKey:@"name"];
valueForKey:首先查找以name或isName命名的getter方法,如果不存在getter方法据悔,就在對(duì)象內(nèi)部查找名為_name或name的實(shí)例變量
注意传透,下列語(yǔ)句是合法的
NSLog(@"age is %@", [student valueForKey:@"age"]);
NSLog中的%@輸出一個(gè)對(duì)象,但age是一個(gè)int值极颓,而不是對(duì)象朱盐,為什么會(huì)合理呢?原因如下:
使用valueForKey:時(shí)菠隆,KVC會(huì)自動(dòng)將標(biāo)量值(int兵琳、float、struct等)翻入NSNumber或NSValue中包裝成一個(gè)對(duì)象骇径,然后返回躯肌。因此,KVC有自動(dòng)包裝功能破衔。
3.批處理
KVC可以對(duì)對(duì)象進(jìn)行批量更改
例如羡榴,同時(shí)獲取Student的age和name
NSArray *keys = [NSArray arrayWithObjects:@"name", @"age", nil];
NSDictionary *dict = [student dictionaryWithValuesForKeys:keys];
同時(shí)設(shè)置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)
除了通過(guò)鍵設(shè)置值外,KVC還支持鍵路徑运敢,像文件系統(tǒng)路徑一樣校仑,其實(shí)就是屬性鏈?zhǔn)皆L問(wèn)
比如忠售,利用鍵路徑設(shè)置Student對(duì)象中Card對(duì)象的no
[student setValue:@"12345" forKeyPath:@"card.no"];
獲取Student對(duì)象中Card對(duì)象的no
[student valueForKeyPath:@"card.no"];
5.數(shù)組的整體操作
如果向一個(gè)NSArray請(qǐng)求一個(gè)key,KVC會(huì)查詢數(shù)組中的每個(gè)對(duì)象來(lái)查找這個(gè)key迄沫,然后將查詢結(jié)果打包到另一個(gè)數(shù)組中并返回
例如稻扬,Student里面有很多Book對(duì)象
獲取Student中所有Book的name
NSArray *names = [student.books valueForKeyPath:@"name"]; 或者
NSArray *names = [student valueForKeyPath:@"books.name"];
注意:不能在鍵路徑中為數(shù)組添加索引,比如@"books[0].name"
6.鍵路徑的運(yùn)算符
在鍵路徑中羊瘩,可以引用一些運(yùn)算符來(lái)進(jìn)行一些運(yùn)算泰佳,例如獲取一組值的平均值、最小值尘吗、最大值或者總數(shù)
例如逝她,計(jì)算Student中Book的總數(shù)
NSNumber *count = [student.books valueForKeyPath:@"@count"];? 或者
NSNumber *count = [student valueForKeyPath:@"books.@count"];
計(jì)算Student中所有Book的價(jià)錢(price)總和
NSNumber *sum = [student.books valueForKeyPath:@"@sum.price"]; 或者
NSNumber *sum = [student valueForKeyPath:@"books.@sum.price"];
找出Student中Book的所有不同價(jià)位(排除相同價(jià)位)
NSArray *prices = [student.books valueForKeyPath:@"@distinctUnionOfObjects.price"];
或者
NSArray *prices = [student valueForKeyPath:@"books.@distinctUnionOfObjects.price"];
7.KVO(key value observing)
KVO是一種非常重要的機(jī)制,它允許監(jiān)聽對(duì)象的屬性的變化
注冊(cè)監(jiān)聽器
-(void)addObserver:(NSObject *)anObserver forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context
anObserver :監(jiān)聽器對(duì)象
keyPath :監(jiān)聽的屬性
options :決定了當(dāng)屬性改變時(shí)睬捶,要傳遞什么數(shù)據(jù)給監(jiān)聽器
監(jiān)聽器需要實(shí)現(xiàn)監(jiān)聽方法
-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)objectchange:(NSDictionary *)change context:(void *)context
keyPath :監(jiān)聽的屬性
object :誰(shuí)的屬性改變了
change :屬性改變時(shí)傳遞過(guò)來(lái)的信息(取決于添加監(jiān)聽器時(shí)的options參數(shù))
移除監(jiān)聽器
-(void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath