私が理解しているように、実装されていないメソッドは次の方法で解決されます。
- resolveInstanceMethod: / resolveClassMethod: メソッドを実装する機会を得る
- forwardingTargetForSelector: デリゲートに転送する機会を取得します
- 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
ファウンデーションで何をするか知っている人はいますか?