2

次のようにすると、コンパイラは文句を言いません。

id foo;
[foo retain];

ただし、次のようにすると、コンパイラは文句を言います。

id<NSCopying> bar;
[bar retain];

具体的には、次のように述べています。

Instance method '-retain' not found (return type defaults to 'id')

どうしてこれなの?idは一般的な Objective-C オブジェクトを指しており、retain任意の Objective-C オブジェクトに渡すことができると考えました。

これは警告であり、エラーではないことに注意してください。そのため、コードをコンパイルでき、動作しているように見えます。また、警告を抑制するために次のことができることにも気付きました。

[(id)bar retain];

id<NSCopying>しかし、 は のサブタイプだと思うidので、 で実行できることは...idで実行できます。id <NSCopying>

4

1 に答える 1

2

必ずしもObjective-C オブジェクトretainに送信できるとは限りません。retainNSObject プロトコルの一部です。たまたますべての Cocoa が NSObject に準拠していますが、言語の観点からはまだ普遍的ではありません (NSObject に準拠していないクラスを定義したり、NSObject クラスから継承したりすることは可能ですが、そうではありません)。非常に便利)。

何かを as として宣言することid<NSCopying>は、「NSCopying プロトコルでのみメッセージを送信できるようにする」ことを意味し、NSCopying にはretain. idNSObject プロトコルからメッセージを送信するには、変数を(この場合、型チェックは行われません)、id<NSObject>(この場合、NSObject プロトコルでのみメッセージを送信できます)、またはクラスのインスタンスとして宣言する必要があります。NSObject に準拠しています。

何かを として宣言している場合、通常は の代わりにid<NSCopying>オブジェクトを送信する必要があります。NSCopying が独自のプロトコルのためにここに立っている場合は、次のように定義することで、プロトコル自体を NSObject に準拠させることができます。copyretain

@protocol YourProtocol <NSObject>

また、2 つのプロトコルに準拠する変数を本当に宣言する必要がある場合 (これは非常に珍しいことですが、ときどき発生する可能性があります)、id<NSCopying,NSObject>.

于 2013-09-13T20:10:30.350 に答える