11

Objective-Cでの動的型付けがどのように機能するかに興味があります。私は「id」タイプを研究していて、それが何をするのか、そしてそれをどのように使うのかを知っています、しかし私は興味があります...そのような機能はどのように内部で実装されますか?

コンパイル時には何も決定/解決できず、実行時にのみ解決できます。メモリ内のオブジェクトの最初のバイトを指すだけでよいと思いますが、クラスシグネチャはどのように保存されますか?現在何を指しているのかをどのように知るのでしょうか。また、指しているオブジェクトのクラスにさまざまなゲッターをどのように実装するのでしょうか。

4

2 に答える 2

15

「内部」、いわば、すべての Objective-C オブジェクトは、その型を表す Class オブジェクトへのポインターを持つ C 構造体です。Anidは、次のような最も基本的な構造体へのポインターです。

struct objc_object {
    Class isa;
}

idより厳密に型指定された変数を使用する場合のように、オブジェクトがどのセレクターにも応答しない可能性があるという警告をコンパイラーが表示しないという点で、コンパイラーによって特別に扱われます。

任意のオブジェクトでメソッドを呼び出すとisa、Class オブジェクトへのポインターに従い、その Class オブジェクトを調べて、呼び出そうとしたメソッドのセレクターの実装関数を見つけます。

于 2011-04-05T17:41:48.757 に答える
7

Anomieの回答に追加すると、クラスがどのメッセージに応答するか、およびそれらのメッセージが呼び出すコードのビットのテーブルをどのように格納するかは完全に不透明です。したがって、Apple の実装がどのように機能するかについて正確に答えることは誰にもできない程度があり、GNU の実装と異なることはほぼ確実です。

ただし、Apple のObjective-C Runtime Referenceでは、ランタイムが実行できるすべてのことを C レベルで説明しています。そのため、設定と検索のためにどのような操作が可能なのかがわかります。これは内部の比較的単純なシステムであり、セレクターから IMP 関数ポインターなど、あるものを別のものにマップする (屈折していない意味での) 単なる一連の辞書です。テーブルに特定のクラスのエントリがある場合、関連するものが呼び出されます。そうでない場合は、スーパークラスがチェックされ、標準のforwardingTargetForSelector:フォールバック メカニズムが考慮されます。

さらに具体的なコメントには、より具体的な質問が必要です。キー値の監視がメソッド スウィズルによって実現されるなどの詳細がたくさんあります (そのため、ランタイムは、クラスがセッターに対して呼び出す C ポインターを、実際のセッターを呼び出して監視しているユーザーに通知するものになるように調整します)。それらはすべて、文書化されているランタイムの特定の用途にすぎません。

于 2011-04-05T18:42:52.743 に答える