6

私が理解しているように、実装されていないメソッドは次の方法で解決されます。

  1. resolveInstanceMethod: / resolveClassMethod: メソッドを実装する機会を得る
  2. forwardingTargetForSelector: デリゲートに転送する機会を取得します
  3. forwardInvocation: 適切と思われる方法でメソッドを処理する機会を取得します。

この 3 段階のプロセスはどこで定義されていますか? NSInvocation は私のニーズには重すぎるかもしれないので、自分で処理したいと思います。ランタイム ソースを調べてみましたが、実際には何も見えません。

古いランタイムはこれを行うためにレシーバーで forward:args: を呼び出すように見えますが、それは新しいランタイムからはなくなったようです。メッセージを処理するために NSInvocation を必要とする程度まで、ランタイムが Cocoa に依存しているとしたら、奇妙なことになるので、プロセスはランタイムではなくフレームワークによって定義されなければならないと推測しています。NSObject / NSProxy で呼び出される文書化されていないメソッドですか?

編集:

objc_msgSend が実装を見つけられない場合に呼び出される C 関数をランタイムが宣言しているように見えますが、定義していません。

id objc_msgForward(id object,SEL message,...);

私は Apple で働いていないので、Foundation がこれをどのように実装しているかはわかりませんが、少なくとも Cocotron の場合は、次のように使用されています。

id objc_msgForward(id object,SEL message,...)
{
   Class       class=object->isa;
   struct objc_method *method;
   void       *arguments=&object;

   if((method=class_getInstanceMethod(class,@selector(forwardSelector:arguments:)))!=NULL)
        return method->method_imp(object,@selector(forwardSelector:arguments:),message,arguments);
   else
   {
       OBJCRaiseException("OBJCDoesNotRecognizeSelector","%c[%s %s(%d)]", class_isMetaClass(class) ? '+' : '-', class->name,sel_getName(message),message);
       return nil;
   }
}

メソッドを追加してforwardSelector:arguments:もうまくいかないようなので、これはココトロン特有のものだと思います。objc_msgForwardファウンデーションで何をするか知っている人はいますか?

4

1 に答える 1

6

メッセージ転送を使用して Objective-C とやり取りするスクリプト言語のようなものを書いています。今のところ、私は NSInvocation を使用していますが、これを 1 秒あたり何千回も実行することになる可能性があるため、オーバーヘッドが顕著になります。でも、好奇心もあると思います…

メッセージ転送に関する限り、動作はプラットフォームやランタイムのバージョンによって [しばしば微妙に] 異なります。

いずれにせよ、車輪を再発明しないでください。今日利用可能な 2 つの言語ブリッジがあり、完全に忠実なブリッジングにかなり近く、そこから多くのことを学ぶことができます。両方とも、そのような再利用を特に許可する自由なライセンスを持っています。

具体的には、MacRuby プロジェクトは、CoreFoundation と Objective-C ガベージ コレクターの上にある Ruby 実装を提供します。これは利用可能な「最もネイティブな」ブリッジです (結果として移植性はそれほど高くありません -- プロジェクトの目標ではありません)。

PyObjC ブリッジは、Objective-C ランタイムと別の動的 OO 言語のランタイムとの間の忠実度の高いブリッジとして利用できる最良の例です。パイソン。Mac OS X 以外のビットは多少腐敗している可能性がありますが、移植性は少し高くなります。

(F-Script について触れないのは怠慢です。Objective-C に基づいて構築された新しい言語で、そのソースが利用可能/利用可能だったと思いますか?)

すべてのブリッジは、メソッド転送、サブクラス化、およびクロスランタイム プロキシの両方を処理します。これらはすべて、特定のニーズに適用できるように思えます。

于 2011-01-29T18:57:37.750 に答える