進行 iOS 開發時,總有一個容易讓人困惑的地方。
那就是 Objective-C 類別別與 Swift extension 的差異。
兩者都能為既有類別新增功能,因此很容易被當成相同概念。
先說結論:兩者外觀看似相近,但適用對象與運作方式相當不同。
類別別只能套用在類別上,並於執行階段運作;extension則可套用在結構、列舉與協定上,並於編譯時決定。
今天會從實務角度逐一比較這兩者。
什麼是 Objective-C 類別別?
類別別(Category)是一種不繼承既有類別,也能新增方法的語法。
例如,即使沒有原始程式碼,也能為像 NSString 這類框架類別加入自己的方法。
不需要原始程式碼。
// NSString 新增電子郵件驗證方法
@interface NSString (Validation)
- (BOOL)isValidEmail;
@end
重點在於,方法會在執行階段附加到類別上。
因此它很有彈性,但若兩個類別別定義了相同方法,也會有無法保證哪一個優先的風險。
類別別之間發生名稱衝突時,很容易演變成難以找出原因的錯誤。
Swift extension 有什麼不同?
把 Swift 的 extension 想成類別別的擴充版,會比較容易理解。
除了方法之外,還能加入計算屬性、初始化器、巢狀型別,以及協定遵循。
更重要的是,它不只限於類別。
結構(struct)、列舉(enum)和協定也都能使用。
// String 新增計算屬性
extension String {
var isValidEmail: Bool {
contains("@") && contains(".")
}
}
尤其是透過協定 extension 提供預設實作,這是 Objective-C 類別別沒有的強大功能。
它能大幅減少重複程式碼。
類別別 vs extension:核心差異一覽
為了方便容易混淆的讀者,整理成表格如下。(以 2026 年語法為準)
| 分類 | Objective-C 類別別 | Swift extension |
|---|---|---|
| 適用對象 | 僅限類別 | 類別、結構、列舉、協定 |
| 計算屬性 | 無法直接使用 | 可以 |
| 儲存屬性 | 不可以 | 不可以 |
| 協定預設實作 | 不可以 | 可以 |
| 方法名稱衝突 | 存在執行階段風險 | 在編譯階段防止 |
| 運作時機 | 執行階段 | 編譯時 |
兩者也有一個共同點。
兩者都無法新增儲存屬性(stored property)。
如果真的想附加狀態,就必須使用 Objective-C 的 associated object 方式,但這不算是推薦做法。
實務上該在什麼時候使用哪一個?
以下分享我在專案中整理出的判斷標準。
- 如果是純 Swift 專案,我會毫不猶豫地使用 extension。
- 如果要維護舊有的 Objective-C 程式碼,就直接沿用類別別。
- 如果要把共用功能提供給多個型別,協定 extension 幾乎就是最佳解。
也有許多混用兩者的情況。
因為透過 Objective-C 類別別建立的功能,可以直接在 Swift 中使用。
反過來也請記住,Swift extension 若未加上 @objc,Objective-C 端就看不到它。
忽略這一點,很容易在橋接過程中遇到編譯錯誤。
總結來說,類別別是專屬於類別的執行階段擴充,而 extension 則是涵蓋幾乎所有型別的編譯時擴充。
只要確實掌握兩者的特性,程式碼結構就會整潔許多。
祝你今天也享受愉快的開發時光!

