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方式を使う必要がありますが、必ずしも推奨はしません。
実務ではいつ、何を使う?
プロジェクトで感じた判断基準を紹介します。
- 純粋なSwiftプロジェクトなら、迷わずextensionを使います。
- 古いObjective-Cコードを保守するなら、カテゴリをそのまま活用します。
- 共通機能を複数の型に適用するなら、プロトコルextensionが最適解に近いでしょう。
併用するケースも多くあります。
Objective-Cカテゴリで作った機能を、Swiftからそのまま利用できるためです。
一方、Swift extensionは@objcを付けないとObjective-C側から見えない点も覚えておきましょう。
ここを見落とすと、ブリッジング中にコンパイルエラーが起きやすくなります。
まとめると、カテゴリはクラス専用のランタイム拡張、extensionはほぼすべての型を対象にしたコンパイル時拡張です。
性質を押さえておけば、コード構造はよりきれいになります。
今日も楽しい開発を!

