カテゴリの主な理由は、ソース コードがないクラスやソース コードを変更したくないクラスにメソッドを追加できるようにすることです。
例 1。
UIImageアニメーション GIF を読み込んでアニメーションを作成する方法が必要でした。論理的には、これはUIImageクラス メソッドである必要がありますが、UIKit フレームワーク ( を含む) のソース コードがありませんUIImage。UIImageそこで、 という名前のクラス メソッドを追加するためのカテゴリを作成しましanimatedImageWithAnimatedGIFData:た。私のuiimage-from-animated-gifリポジトリで見つけることができます。
このメソッドを に追加する必要がありましたUIImageか? いいえ、通常の C 関数にすることもAnimatedGIFLoader、メソッドを保持するユーティリティ クラス (おそらく という名前) にすることもできました。しかし、設計の観点からは、メソッドは論理的に に属しUIImageます。
例 2。
Apple は、文字列をグラフィック コンテキストに簡単に描画できるようにしたいと考えていました。NSStringGUI を使用するプログラムでは、draw メソッドを使用するのが合理的です。Apple は Foundation フレームワーク ( を含むNSString) のソース コードを持っているので、それを追加することができます。しかし、Foundation フレームワークは、ユーザー インターフェイスを持たないプログラムを含む、あらゆる種類のプログラムで使用できるように設計されています。したがって、Foundation のクラスは、UIKit、AppKit、Core Graphics、またはグラフィックスを描画できるその他の高レベル ライブラリについて何も知りません。
代わりに、UIKit にはdrawAtPoint:withFont:メソッドを に追加するカテゴリがありますNSString。AppKit には、drawAtPoint:withAttributes:メソッドを に追加するカテゴリがありますNSString。
AppKit と UIKit には、Foundation クラスにメソッドを追加する他の多くのカテゴリがあります。たとえば、UIKit には 、 、 などのカテゴリがNSObjectありNSIndexPathますNSCoder。
.mカテゴリを使用するもう 1 つの理由は、クラスの実装を複数のファイルに分割することです。大きなクラスがある場合は、そのセレクターの一部をカテゴリに移動し、別のソース ファイルにカテゴリ メソッドを実装できます。リンカーは、実行可能ファイルを作成するときにカテゴリをクラスに自動的にマージするため、実行時のペナルティはありません。