標籤:ios開發基礎 oc kvc 索引值編碼 key-value
結合之前的學習筆記以及參考《Objective-C編程全解(第三版)》,對Objective-C知識點進行梳理總結。知識點一直在變,只是作為參考,以蘋果官方文檔為準~
十七、索引值編碼 KVC
關於KVC的知識點將通過下列例子來展開說明:
Person.h檔案,Person類擁有name和age兩個成員變數
@interface Person : NSObject { @private NSString *_name; NSInteger _age; } - (void)setAge:(NSInteger)age; @end
Person.m實現了該方法
@implementation Person - (NSString *)description { return [NSString stringWithFormat:@"name:%@,age=%li", _name, _age]; } - (void)setAge:(NSInteger)age { _age = age; } @end
main.m
Person *p = [[Person alloc] init]; // p->_name = @"Zane"; 不可訪問 //1.使用KVC給private的屬性設定值 [p setValue:@"Zane" forKey:@"name"]; //2.通過KVC擷取到屬性值 NSString *name = [p valueForKey:@"_name"]; NSLog(@"%@", name); [p setValue:@21 forKey:@"age"]; NSLog(@"%@", p);
output:
2015-07-09 17:29:43.477 exercise_KVC[579:24344] Zane2015-07-09 17:29:43.478 exercise_KVC[579:24344] name:Zane,age=21
1、索引值編碼(key-value coding):將表示對象包含的資訊的字串作為索引值使用,來間接訪問該資訊的方式。
基本上,只要存在訪問器方法、聲明屬性或執行個體變數,就可以將其名字作為字串訪問。(即使這個變數時@private私人的,也能訪問)
2、設定屬性值:
- (void)setValue:(id)value forKey:(NSString *)key; //已進行記憶體管理 [p setValue:@"Zane" forKey:@"name"];
a、如果此處name寫錯了,寫成nama,nam1e等等,編譯器不會報錯,但會導致運行崩潰
b、value為id類型,因此如果是基礎資料型別 (Elementary Data Type)需要進行封裝
擷取屬性值
- (id)valueForKey:(NSString *)key; NSString *name = [p valueForKey:@"_name"];
如果人還擁有一條狗,以@class的方式加在Person.h中,狗有dogName屬性,那麼可以指定路徑設定
[p setValue:@"wangwang" forKeyPath:@"dog._dogname"];NSLog(@"%@",[p valueForKeyPath:@"dog._dogname"])
- (id)valueForKeyPath:(NSString *)keyPath;- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;
3、缺點
(1)破壞了物件導向的封裝性;
(2)編譯器不會對設定的keyValue進行錯誤檢查;
(3)需要先對字串進行解析,執行效率低於set和get方法
4、其他說明
(1)使用KVC設定屬性,優先去當前類中尋找是否有相應的set方法,如果有使用set方法設定,若無則找到屬性設定
要調用只能寫age不能寫_age
例如例子中的
[p setValue:@21 forKey:@"age"];[p setValue:@21 forKey:@"_age"];
可以在age的set方法實現處設定斷點,會發現,如果寫_age則不調用set方法
(2)一對多的關係
一般先打包成NSArray,再通過setValue方法,作為value賦值。
訪問的時候通過路徑訪問valueForKeyPath訪問
(3)數值計算
在上述例子中為Person增加book成員變數;
並且Dog.h擁有成員變數dogage
@interface Dog : NSObject { int _dogage; } - (instancetype)initWithAge:(int)age; //並實現 @end
main.m
Dog* dog1 = [[Dog alloc] initWithAge:20]; Dog* dog2 = [[Dog alloc] initWithAge:30]; Dog* dog3 = [[Dog alloc] initWithAge:10]; NSArray *array = [NSArray arrayWithObjects:dog1,dog2,dog3, nil]; [p setValue:array forKey:@"dog"]; //前面已定義 NSLog(@"%@",[p valueForKeyPath:@"[email protected]"]); //dog數量 NSLog(@"%@",[p valueForKeyPath:@"[email protected]_dogage"]); //所有dogage總和 NSLog(@"%@",[p valueForKeyPath:@"[email protected]_dogage"]); //平均值 NSLog(@"%@",[p valueForKeyPath:@"[email protected]_dogage"]); //最小值 NSLog(@"%@",[p valueForKeyPath:@"[email protected]_dogage"]); //最大值
output:
2015-07-09 17:29:43.479 exercise_KVC[579:24344] 32015-07-09 17:29:43.479 exercise_KVC[579:24344] 602015-07-09 17:29:43.480 exercise_KVC[579:24344] 202015-07-09 17:29:43.480 exercise_KVC[579:24344] 102015-07-09 17:29:43.480 exercise_KVC[579:24344] 30
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
Objective-C(十七、KVC索引值編碼及執行個體說明)——iOS開發基礎