早期 Objective-C (MRC/早期 ARC) 需手動宣告實例變數(ivar)並配合 @synthesize:
// .h
@interface MyClass : NSObject
@property (nonatomic, strong) NSString *name;
@end
// .m (舊寫法)
@interface MyClass () {
NSString *_name; // 手動宣告 ivar
}
@end
@implementation MyClass
@synthesize name = _name; // 手動綁定
- (void)dealloc {
[_name release];
[super dealloc];
}
@end
自 Xcode 4.4 / LLVM 4.0 起,編譯器預設自動合成:
_propertyName (底線前綴)@synthesize、無需在 @interface 區塊宣告 ivar// MyClass.h
@interface MyClass : NSObject
@property (nonatomic, copy) NSString *name; // 建議 copy 修飾 NSString
@property (nonatomic, assign) NSInteger age;
@end
// MyClass.m
@implementation MyClass
// 完全空白!所有存取器、ivar 皆由編譯器自動生成
@end
若覆寫 Getter/Setter,編譯器不再自動生成 ivar,需手動 @synthesize 或在 @implementation 區塊加 @dynamic:
@implementation MyClass
@synthesize name = _name; // 覆寫 setter 時必須手動綁定
- (void)setName:(NSString *)name {
_name = [name copy]; // 自訂邏輯
}
@end
| 誤區 | 事實 |
|---|---|
| 「@property 只是宣告,還要寫 ivar」 | 現代編譯器自動生成 _ivar |
| 「一定要寫 @synthesize」 | 未覆寫存取器時完全不需要 |
| 「atomic vs nonatomic 影響 ivar 生成」 | 只影響 setter 實作細節,ivar 一樣自動生成 |
專注於 .h 宣告 @property,.m 保持空白,讓編譯器處理樣板代碼。若需自訂存取邏輯,再補上 @synthesize 並操作 _ivar。這是現代 Objective-C 開發的標準姿勢。