| 特性 | Class Extension (類別擴展) | Category (分類) |
|---|---|---|
| 語法 | @interface ClassName () | @interface ClassName (CategoryName) |
| 匿名性 | ✅ 無名稱 | ❌ 必須命名 |
| 方法實現位置 | ✅ 必須 在主 @implementation 中 | ❌ 可在獨立 @implementation CategoryName 中 |
| 編譯器驗證 | ✅ 未實現 → 編譯警告/錯誤 | ❌ 無驗證,執行時才發現缺失 |
| 屬性重宣告 | ✅ 可改變屬性特質(readonly→readwrite) | ❌ 不可改變原屬性特質 |
| 實例變數 | ✅ 可添加 (現代 Runtime) | ❌ 傳統無法添加 (關聯物件除外) |
| 可見範圍 | 僅實現檔 (.m) 內可見 | 匯入標頭檔即可見 |
// MyClass.h
@interface MyClass : NSObject
- (void)publicMethod;
@end
// MyClass.m (傳統)
@interface MyClass (Private) // 命名 Category
- (void)awesomePrivateMethod;
@end
@implementation MyClass (Private) // 獨立實現區塊
- (void)awesomePrivateMethod { ... }
@end
@implementation MyClass
- (void)publicMethod { ... }
@end
❌ 問題:編譯器認為 Private Category 方法在別處實現,不檢查是否真正實現。
// MyClass.m
@interface MyClass () // 匿名擴展
- (void)awesomePrivateMethod;
@property (nonatomic, strong) id privateData;
@end
@implementation MyClass
// 所有私有方法、屬性必須在這裡實現,否則編譯錯誤
- (void)awesomePrivateMethod { ... }
- (void)publicMethod { ... }
@end
✅ 優勢:編譯期保證所有宣告皆有實現,重構安全。
// MyClass.h (公開介面)
@interface MyClass : NSObject
@property (nonatomic, readonly) float progress; // 外部唯讀
@end
// MyClass.m (私有擴展)
@interface MyClass ()
@property (nonatomic, readwrite) float progress; // 內部可寫
@end
@implementation MyClass
- (void)updateProgress:(float)p {
_progress = p; // 內部可直接賦值
// 或 self.progress = p; (經由 setter)
}
@end
外部代碼:obj.progress ✅ 讀取;obj.progress = 0.5 ❌ 編譯錯誤。
內部代碼:_progress = 0.5 ✅ 或 self.progress = 0.5 ✅。
// Category
@interface MyClass (Additions)
- (void)extraMethod;
@end
// Class Extension
@interface MyClass ()
- (void)privateMethod;
@end
關鍵區別:括號中是否有名稱。有名稱 = Category;空 = Extension。
@interface MyClass ()
{
NSString *_cachedDescription; // 實例變數
int _internalCounter;
}
@property (nonatomic, copy) NSString *cachedDescription;
@end
⚠️ 僅支援 64-bit macOS / iOS。32-bit 舊版 Runtime 不支援。
| 場景 | 推薦方案 |
|---|---|
| 私有方法、私有屬性、實現細節 | Class Extension (在 .m 檔頂部) |
| 公開 API 擴展、跨檔案組織代碼 | Category (獨立 .h/.m) |
| 第三方類添加方法 | Category (無法用 Extension) |
| 公開唯讀、內部可寫屬性 | Extension 重宣告屬性特質 |
| 協議實現分組 | Category (如 MyClass+UITableViewDelegate) |