クラス拡張機能@interface Class ()
はより強力で、変数をクラスに挿入できます。カテゴリ@interface Class (Category)
はできません。
他にどのような違いがありますか? クラス拡張よりもカテゴリを使用する必要があるのはいつですか?
クラス拡張機能@interface Class ()
はより強力で、変数をクラスに挿入できます。カテゴリ@interface Class (Category)
はできません。
他にどのような違いがありますか? クラス拡張よりもカテゴリを使用する必要があるのはいつですか?
主な違いは、拡張機能を使用すると、コンパイラは main 内にメソッドを実装することを期待するの@implementation
に対し、カテゴリを使用すると別の@implementation
ブロックがあることです。したがって、ほとんどの場合、メイン ファイルの先頭でのみ拡張子を使用する必要があります.m
(ちなみに、ivar を気にする必要がある唯一の場所です) 。
クラス エクステンションはカテゴリと似ていますが、コンパイル時にソース コードがあるクラスにのみ追加できます (クラスはクラス エクステンションと同時にコンパイルされます)。クラス拡張によって宣言されたメソッドは、元のクラスの @implementation ブロックに実装されるため、たとえば、フレームワーク クラス (NSString などの Cocoa または Cocoa Touch クラスなど) でクラス拡張を宣言することはできません。
クラス拡張を宣言する構文は、カテゴリの構文に似ており、次のようになります。
@interface ClassName ()
@end
括弧内に名前が指定されていないため、クラス拡張はしばしば匿名カテゴリと呼ばれます。
通常のカテゴリとは異なり、クラス拡張は独自のプロパティとインスタンス変数をクラスに追加できます。次のように、クラス拡張でプロパティを宣言する場合:
@interface XYZAnimal () {
id _someCustomInstanceVariable;
}
...
@end
私見ですが、クラス拡張はクラスへのプライベート インターフェイスと考えるのが最善です。プライマリ インターフェイス (.h ファイル内) は、他のクラスとのクラスの動作契約を定義するパブリック インターフェイスとして機能します。
クラス拡張機能を使用して個人情報を非表示にする
クラス拡張は、多くの場合、クラス自体の実装内で使用する追加のプライベート メソッドまたはプロパティでパブリック インターフェイスを拡張するために使用されます。たとえば、プロパティをインターフェイスで readonly として定義するのが一般的ですが、実装の上で宣言されたクラス拡張では readwrite として定義し、クラスの内部メソッドがプロパティ値を直接変更できるようにします。
例として、XYZPerson クラスは、米国の社会保障番号などの情報を追跡するように設計された、uniqueIdentifier と呼ばれるプロパティを追加する場合があります。
通常、現実世界で一意の識別子を個人に割り当てるには大量の事務処理が必要になるため、XYZPerson クラス インターフェイスはこのプロパティを読み取り専用として宣言し、次のように識別子の割り当てを要求するメソッドを提供します。
@interface XYZPerson : NSObject
...
@property (readonly) NSString *uniqueIdentifier;
- (void)assignUniqueIdentifier;
@end
XYZPerson クラスがプロパティを内部的に変更できるようにするには、クラスの実装ファイルの先頭で定義されているクラス拡張でプロパティを再宣言するのが理にかなっています。
@property (readwrite) NSString *uniqueIdentifier;
注: readwrite 属性はデフォルトであるため、オプションです。明確にするために、プロパティを再宣言するときに使用したい場合があります。
カテゴリは、既存のクラスに新しいメソッドを追加できるようにする Objective-C 言語の機能です。拡張機能は、メインの実装ブロックで実装する必要があるメソッドを定義できるカテゴリの特殊なケースです。
プライベート宣言は、メソッドを呼び出す前に宣言する必要がないため、主にいくつかのプロパティであるクラス拡張に含めることができます。
c# に類似した ios 拡張機能、Java 抽象クラスまたはインターフェース
c# クラス拡張に類似した ios カテゴリ