Swift & Objective-C

Objective-CのカテゴリとSwift extensionの違い(概念・注意点まとめ)

iOS開発では、一度は戸惑うポイントがあります。

読了 4 分
Objective-CのカテゴリとSwift extensionの違い(概念・注意点まとめ)のカバー画像

iOS開発では、一度は戸惑うポイントがあります。

それがObjective-CのカテゴリとSwift extensionの違いです。

どちらも「既存のクラスに機能を追加する」点が似ているため、同じ概念だと思いがちです。

結論から言うと、見た目は似ていますが、対象と動作方式はかなり異なります。

カテゴリはクラス専用でランタイムに動作しますが、extensionは構造体・列挙型・プロトコルにも使え、コンパイル時に決まります。

今回は、この2つを実務の観点から順に比較します。


Objective-Cのカテゴリとは?

カテゴリ(Category)は、既存クラスを継承せずにメソッドを追加する構文です。

たとえば、NSStringのようなフレームワーククラスにも独自メソッドを追加できます。

ソースコードがなくても構いません。

// NSStringにメール検証メソッドを追加
@interface NSString (Validation)
- (BOOL)isValidEmail;
@end

ポイントは、ランタイムでメソッドがクラスに追加されることです。

柔軟な一方、2つのカテゴリが同じメソッドを定義すると、どちらが優先されるか保証されない危険があります。

カテゴリ間で名前が重複すると、原因を特定しにくいバグにつながりがちです。


Swift extensionは何が違う?

Swiftのextensionは、カテゴリの拡張版と考えると分かりやすいでしょう。

メソッドだけでなく、計算プロパティ、イニシャライザ、ネスト型、プロトコル準拠も追加できます。

何より、クラスだけに限定されません。

構造体(struct)、列挙型(enum)、プロトコルにも使えます。

// Stringに計算プロパティを追加
extension String {
    var isValidEmail: Bool {
        contains("@") && contains(".")
    }
}

特に、プロトコルextensionでデフォルト実装を提供できる点は、Objective-Cカテゴリにはない強力な機能です。

重複コードを大幅に減らせます。


カテゴリとextensionの主な違いを一目で比較

混乱しやすい点を、2026年の構文基準で表にまとめました。

項目 Objective-Cカテゴリ Swift extension
適用対象 クラスのみ クラス・構造体・列挙型・プロトコル
計算プロパティ 直接は不可 可能
保存プロパティ 不可 不可
プロトコルのデフォルト実装 不可 可能
メソッド名の衝突 ランタイム上の危険あり コンパイル段階で防止
動作時点 ランタイム コンパイル時
表にまとめると、違いがより明確に分かります。
表にまとめると、違いがより明確に分かります。

共通点も1つあります。

どちらも保存プロパティ(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はほぼすべての型を対象にしたコンパイル時拡張です。

性質を押さえておけば、コード構造はよりきれいになります。

今日も楽しい開発を!

あわせて読みたい