Objective-C では、C とid
まったく同じvoid *
ですか? (汎用ポインター型)。
もしそうなら、私たちが使用するとき
id obj = [[Fraction alloc] init];
[obj methodName];
obj = [[ComplexNumber alloc] init];
[obj anotherMethodName];
メソッドが呼び出されたとき、プログラムはどのような方法でクラスobj
が何であるかを認識しますか?
Objective-C では、C とid
まったく同じvoid *
ですか? (汎用ポインター型)。
もしそうなら、私たちが使用するとき
id obj = [[Fraction alloc] init];
[obj methodName];
obj = [[ComplexNumber alloc] init];
[obj anotherMethodName];
メソッドが呼び出されたとき、プログラムはどのような方法でクラスobj
が何であるかを認識しますか?
id
Objective-C では、C とまったく同じではありませんvoid *
。
Apple の「The Objective-C プログラミング言語」から:
typedef struct objc_object {
Class isa;
} *id;
つまり、id
はobjc_object
構造体へのポインタであり、へのポインタとは異なりますvoid
。
したがって、すべてのオブジェクト
isa
には、インスタンスであるクラスを示す変数があります。Class
型自体がポインターとして宣言されているためです。
typedef struct objc_class *Class;
また、メソッド呼び出し中にプログラムがクラスにどのように伝えるかについても教えてください。、これは上記で引用した同じプログラミング ガイドからのものです。
isa
インスタンス変数は、オブジェクトのクラス(オブジェクトの種類) を識別します。同じ動作 (メソッド) と同じ種類のデータ (インスタンス変数) を持つオブジェクトは、同じクラスのメンバーです。したがって、オブジェクトは実行時に動的に型付けされます。必要なときはいつでも、ランタイム システムは、オブジェクトに尋ねるだけで、オブジェクトが属している正確なクラスを見つけることができます。(ランタイムの詳細については、「 Objective-C ランタイム プログラミング ガイド」を参照してください。 )
ガイドによると、id
、nil
、およびその他の Objective-C の基本的なタイプは、ヘッダー ファイルで定義されていますobjc/objc.h
。
id
と同じではありませんvoid *
。id
不明な型の Objective C オブジェクトへのポインタです。object
C# や Javaのデータ型のように。Avoid*
は何でも指すことができます。非 nilid
は、すべての ObjC オブジェクトに共通のデータ構造を指し、それぞれのクラス データへのポインターを含むことが期待されます。
ObjC ランタイム - alloc
/ init
/etc の実装。- すべての有効なオブジェクトに正しいクラス ポインタがあることを確認します。
IIRC では、Apple の実装ではid
、ポイントするポインタ サイズの変数は、実際にはクラスへのポインタです。
クラスのデータ ブロックには、メソッド シグネチャをメソッド実装への関数ポインターにマップするメソッドのリストがあります。そこからは、実行時にオブジェクトにメッセージを送信する (つまり、メソッドを呼び出す) ときに発生するかなり単純なルックアップです。また、基本クラスへのポインタで、メソッド ルックアップが継承ツリーを継続できるようにします。
id
ちなみに、静的に安全でない場合、 にメッセージを送信するときに void ポインターの逆参照がコンパイラ エラーになるのはそのためです。
はい、id
単なる一般的なポインターです。コンパイル時のクラス解決は、ユーザーに警告とエラーを通知するだけです。ただし、タイプが id の veritable は、コンパイル時に特定のクラスに関連付けられません。実際のクラスは、実行時にオブジェクトにアクセスするまでわかりません。オブジェクトが のサブクラスでNSObject
ある場合 (その可能性が最も高い)、コードはオブジェクトにそのクラスが何であるかを問い合わせることができます。
[myObject class]
のクラスを返しmyObject
ます。 irが class のメンバーではないことを示す[myObject isMemberOfClass:[SomeClass class]]
を返します。BOOL
myObject
SomeClass
コードが のメソッドをmyObject
呼び出すと、オブジェクトがそのメソッドに応答しなくても、ランタイムは呼び出しを試みます。myObject
がそのメソッドを実装していない 場合、実行時例外が発生します。
myObject
メソッドが で有効かどうかを事前に確認することもできます[myObject respondsToSelector:@selector(myCoolMethod)]
。