Key-Value Coding (KVC) 是 Objective-C 提供的一種間接存取物件屬性的機制:以字串為鍵,透過 valueForKey: 與 setValue:forKey: 訪問屬性,無需呼叫存取方法、無需直接操作實例變數。KVC 方法定義於 NSKeyValueCoding 非正式協定,預設實作由 NSObject 提供。
int、float、BOOL 等)與結構體(CGRect、CGPoint 等),非物件型別會自動裝箱/拆箱(NSNumber、NSValue)。. 分隔符,可鏈式存取關聯物件屬性。@sum、@avg、@max、@min、@count)可對陣列/集合執行聚合運算。呼叫 setValue:forKey: 或 valueForKey: 時,執行順序:
setKey:/key)。_key 或 key。NSUndefinedKeyException。這意味著 KVC 可繞過公開介面,直接存取私有實例變數——雙刃劍,慎用。
Person *person = [[Person alloc] init];
NSMutableString *name = [[NSMutableString alloc] initWithString:@"張三"];
// 設值:自動尋找 setName: 或 _name 實例變數
[person setValue:name forKey:@"name"];
// 取值
NSLog(@"name : %@", [person valueForKey:@"name"]);
// 錯誤:直接傳 int
[person setValue:25 forKey:@"age"]; // 崩潰或未定義行為
// 正確:包裝為 NSNumber
[person setValue:@(25) forKey:@"age"]; // 或 [NSNumber numberWithInt:25]
Person *person = [[Person alloc] init];
Author *author = [[Author alloc] init];
[author setValue:@"iOS 開發" forKey:@"title"];
[person setValue:author forKey:@"author"];
// 單層存取
NSLog(@"name: %@", [person valueForKey:@"name"]);
// 鍵路徑穿透:person.author.title
NSString *title = [person valueForKeyPath:@"author.title"];
NSLog(@"title: %@", title);
當對陣列發送 valueForKey: 時,KVC 會遍歷每個元素取其對應鍵值,並將結果打包成新陣列回傳:
NSMutableArray *persons = [NSMutableArray arrayWithCapacity:3];
for (int i = 0; i < 3; i++) {
Person *p = [[Person alloc] init];
[p setValue:[NSString stringWithFormat:@"person_%d", i] forKey:@"name"];
[persons addObject:p];
}
[person setValue:persons forKey:@"rePerson"];
// 取得所有人的 name 陣列
NSArray *nameArray = [person valueForKeyPath:@"rePerson.name"];
NSLog(@"%@", nameArray); // 輸出: (person_0, person_1, person_2)
// 假設 rePerson 陣列中每個 Person 皆有 age 屬性
NSString *sum = [person valueForKeyPath:@"rePerson.@sum.age"]; // 總和
NSString *count = [person valueForKeyPath:@"rePerson.@count.age"]; // 個數
NSString *max = [person valueForKeyPath:@"rePerson.@max.age"]; // 最大值
NSString *min = [person valueForKeyPath:@"rePerson.@min.age"]; // 最小值
NSString *avg = [person valueForKeyPath:@"rePerson.@avg.age"]; // 平均值
NSLog(@"sum=%@ count=%@ max=%@ min=%@ avg=%@", sum, count, max, min, avg);

| 場景 | 建議 |
|---|---|
| 純量型別屬性 | 務必用 @(...) 或 NSNumber 包裝 |
| 效能敏感路徑 | 優先用直接存取(person.name),KVC 有執行期查找開銷 |
| 鍵名拼寫錯誤 | 編譯器不檢查字串鍵名,建議定義 static NSString *const kNameKey = @"name"; 集中管理 |
| 私有屬性存取 | 僅限單元測試或極少數框架整合場景,業務邏輯禁止濫用 |
KVC 是 Objective-C 動態特性的核心體現,支援鍵路徑穿透、集合映射與聚合運算,極大簡化資料綁定、序列化、表單驗證等場景程式碼。掌握其存取順序、裝箱規則與集合運算子,能讓你在需要動態性時游刃有餘,同時避免濫用帶來的維護風險。