iOS基礎 - KVC and KVO

1、KVCkey value coding

咱們通常是經過調用set方法或屬性的點語法來直接更改對象的狀態,即對象的屬性值,好比[stu setAge:10];  stu.age = 9;數組

KVC,它是一種間接更改對象狀態的方式,其實現方法是使用字符串來描述對象須要更改的屬性。KVC中的基本調用包括valueForKey:setValue:ForKey:,以字符串的形式向對象發送消息 spa

2、valueForKey

使用valueForKey:獲取Student對象的nameserver

NSString *name = [student valueForKey:@"name"];對象

valueForKey:首先查找以nameisName命名的getter方法,若是不存在getter方法,就在對象內部查找名爲_namename的實例變量 索引

 

注意,下列語句是合法的rem

NSLog(@"age is %@", [student valueForKey:@"age"]);字符串

NSLog中的%@輸出一個對象,但age是一個int值,而不是對象,爲何會合理呢?緣由以下:get

使用valueForKey:時,KVC會自動將標量值(intfloatstruct)翻入NSNumberNSValue中包裝成一個對象,而後返回。所以,KVC有自動包裝功能。it

3、setValue:ForKey

使用setValue:ForKey:設置Student對象的nameio

[student setValue:@"MJ" forKey:@"name"];

這個方法的工做方式和valueForKey:相同,首先查找setter方法,例如setName:,若是不存在setter方法,就在類中查找名爲name或者_name的實例變量,而後爲它賦值

 

使用setValue:ForKey:設置Student對象的age

[student setValue:[NSNumber numberWithInt:17] forKey:@"age"];

在設置一個標量值時,須要先將標量值包裝成一個NSNumberNSValue對象

4、批處理

KVC能夠對對象進行批量更改

例如,同時獲取Studentagename

NSArray *keys = [NSArray arrayWithObjects:@"name", @"age", nil];

NSDictionary *dict = [student dictionaryWithValuesForKeys:keys];

 

同時設置Studentagename

NSArray *keys = [NSArray arrayWithObjects:@"name", @"age", nil];

NSArray *values = [NSArray arrayWithObjects:@"MJ", [NSNumber numberWithInt:16], nil];

NSDictionary *dict = [NSDictionary dictionaryWithObjects:values forKeys:keys];

[student setValuesForKeysWithDictionary:dict];

5、鍵路徑(key path)

除了經過鍵設置值外,KVC還支持鍵路徑,像文件系統路徑同樣,其實就是屬性鏈式訪問

好比,利用鍵路徑設置Student對象中Card對象的no

[student setValue:@"12345" forKeyPath:@"card.no"];

獲取Student對象中Card對象的no

[student valueForKeyPath:@"card.no"];

6、數組的總體操做

若是向一個NSArray請求一個keyKVC會查詢數組中的每一個對象來查找這個key,而後將查詢結果打包到另外一個數組中並返回

例如,Student裏面有不少Book對象

 

獲取Student中全部Bookname

NSArray *names = [student.books valueForKeyPath:@"name"]; 或者

NSArray *names = [student valueForKeyPath:@"books.name"];

注意:不能在鍵路徑中爲數組添加索引,好比@"books[0].name"

7、鍵路徑的運算符

在鍵路徑中,能夠引用一些運算符來進行一些運算,例如獲取一組值的平均值、最小值、最大值或者總數

例如,計算StudentBook的總數

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"];

找出StudentBook的全部不一樣價位(排除相同價位)

NSArray *prices = [student.books valueForKeyPath:@"@distinctUnionOfObjects.price"];

或者

NSArray *prices = [student valueForKeyPath:@"books.@distinctUnionOfObjects.price"];

8、KVOkey 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)object change:(NSDictionary *)change context:(void *)context

keyPath :監聽的屬性

object :誰的屬性改變了

change :屬性改變時傳遞過來的信息(取決於添加監聽器時的options參數)

 

移除監聽器 

-(void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath

相關文章
相關標籤/搜索