3

私は最近、objective-c オブジェクトが構造体としてヒープに格納されていることをここで読みました。構造体には、オブジェクト iVar、継承された iVar、および isa ポインターが含まれています。

このオブジェクトにメッセージを送信するタイミングを把握しようとしていますが、ランタイムは実行するコードをどのように判断するのでしょうか?

クラスごとにクラスオブジェクトがあることは知っています。これもヒープに保存されますか?

それが機能する方法は、ランタイムが構造体から isa ポインターを取得し、これを使用してクラス オブジェクトでメッセージを呼び出すことだと思います。これは正しいです?

4

1 に答える 1

11

つまり、すべての Objective-C インスタンスには、そのクラスへのポインターがあります。クラスには、クラスが実装するすべてのメソッドを含むメタデータのインベントリが含まれています。メッセージがオブジェクトに送信されると (メソッドが呼び出されると)、ランタイムはクラスへのポインターを使用して名前でメソッドを検索し、見つかった場合はそれを呼び出します。見つからない場合、ランタイムは NSObject までの継承チェーンでスーパークラス (各クラスのメタデータの一部) を探します。メソッドが最終的に見つからない場合、ランタイムは一連の最後の溝の努力を行って、それらが代替ハンドラーであるかどうかを確認し、そうでない場合は最終的に例外を発生させます。

それ以上の詳細が必要な場合は、Objective-C のメソッド ディスパッチがどのように機能するかについてのマルチパート ツアーを作成しました。 少し古くなっています -- ARC、タグ付きポインタ、IMP としてのブロックは扱っていませんが、まだ完全に適用可能です。


はい、クラスはヒープに格納されますが、通常は malloc() メモリには格納されません。クラスは通常、読み取り専用の共有メモリとしてロードされます。つまり、システムで実行されているすべてのアプリケーションに対してNSString、メモリ内にクラスのコピーが 1 つだけ存在します。その場でクラスを動的に作成することができ、これらは通常のヒープになりますが、それは典型的ではありません。

于 2013-01-08T17:06:31.450 に答える