Swift 與 Objective-C

Objective-C 類別別與 Swift extension 的差異(概念與注意事項總整理)

進行 iOS 開發時,總有一個容易讓人困惑的地方。

閱讀 3 分鐘
Objective-C 類別別與 Swift extension 的差異(概念與注意事項總整理) 封面圖

進行 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 方式,但這不算是推薦做法。


實務上該在什麼時候使用哪一個?

以下分享我在專案中整理出的判斷標準。

  1. 如果是純 Swift 專案,我會毫不猶豫地使用 extension。
  2. 如果要維護舊有的 Objective-C 程式碼,就直接沿用類別別。
  3. 如果要把共用功能提供給多個型別,協定 extension 幾乎就是最佳解。
如果是純 Swift 專案,我會毫不猶豫地使用 extension。
如果是純 Swift 專案,我會毫不猶豫地使用 extension。

也有許多混用兩者的情況。

因為透過 Objective-C 類別別建立的功能,可以直接在 Swift 中使用。

反過來也請記住,Swift extension 若未加上 @objc,Objective-C 端就看不到它。

忽略這一點,很容易在橋接過程中遇到編譯錯誤。


總結來說,類別別是專屬於類別的執行階段擴充,而 extension 則是涵蓋幾乎所有型別的編譯時擴充。

只要確實掌握兩者的特性,程式碼結構就會整潔許多。

祝你今天也享受愉快的開發時光!

延伸閱讀