Objective-C 2.0 引入屬性語法,自動生成存取器,簡化程式碼。本文系統整理屬性宣告/實現、屬性特性、點語法、KVC 機制。
/* .h 宣告 */
@property NSString *name;
/* 相當於生成 */
- (void)setName:(NSString *)name;
- (NSString *)name;
/* .m 實現 (Xcode 4.5+ 自動 @synthesize) */
@synthesize name = _name; /* 手動指定實例變數名稱 */
/* 相當於生成 */
- (void)setName:(NSString *)name { _name = name; }
- (NSString *)name { return _name; }
注意:若在 `.m` 重寫存取器,**必須**保留 `@synthesize`,否則編譯器不會生成實例變數 `_name`。
| 類別 | 關鍵字 | 說明 | 預設 |
|---|---|---|---|
| 讀寫控制 | readonly | 唯讀,僅生成 getter | readwrite |
| readwrite | 可讀寫,生成 setter/getter | ||
| setter=名, getter=名 | 自訂存取器名稱 | ||
| 原子性 | atomic | 多執行緒安全 (鎖),效能較低 | atomic |
| nonatomic | 非原子,**建議預設用此** | ||
| 記憶體語意 | assign | 單純賦值,適用基本類型 | assign |
| retain | 保留新值、釋放舊值,適用物件 (MRC) | ||
| copy | 複製新值,適用 NSString/NSArray 等可變類別 |
組合範例:`@property (nonatomic, copy) NSString *name;`
符合慣例存取器的方法均可用點語法:
[person setName:@"ZhangSan"]; → person.name = @"ZhangSan";
NSString *n = [person name]; → NSString *n = person.name;
本質:編譯器將點語法轉換為對應訊息傳送。
透過字串鍵間接存取屬性/實例變數。
[obj setValue:value forKey:@"key"];
[obj setValue:value forKeyPath:@"key.subKey"]; /* 鍵路徑 */
[obj setValuesForKeysWithDictionary:dict]; /* 批次 */
[obj valueForKey:@"key"];
[obj valueForKeyPath:@"key.subKey"];
- (void)setValue:(id)value forUndefinedKey:(NSString *)key {
NSLog(@"Undefined key: %@", key); /* 預設拋出異常,可覆寫吞掉 */
}
- (id)valueForUndefinedKey:(NSString *)key { return nil; }
見原文件碼,展示 `@property` 多種特性組合、KVC 賦值/取值/鍵路徑/異常處理。
屬性 + `@synthesize` + 特性關鍵字 + 點語法 + KVC 構成 Objective-C 物件屬性管理的完整體系。現代開發 (ARC) 下 `retain`/`copy` 語意由編譯器自動處理,重點掌握 `nonatomic`/`copy` (NSString) 等常用組合。