このキャッチオールプロキシとそれを転送する必要があることについて詳しく説明できますか?プロキシが唯一つのターゲットにそれぞれメッセージを転送する必要がある場合
、それは実行時にその-forwardingTargetForSelector:
で行うことができます。そうでない場合(たとえば、複数のターゲットに転送する必要がある、または他の複雑な操作を行う必要がある場合)、それを処理するには-forwardInvocation:
を実装する必要があります。 -forwardInvocation:
を使用して呼び出しを処理するには、呼び出しを作成できるようにメソッドの署名を取得する必要があるため、-messageSignatureForSelector:
を実装する必要があります。 (それを別のオブジェクトに転送しても、そのオブジェクトは直接メソッドを実装するか、+resolveInstanceMethod:
に対応するメソッドを追加するか、-forwardInvocation:
を使用して処理します)。
メソッドシグネチャは、引数の型と戻り値の型をエンコードします。この情報が呼び出しに必要な理由は、これらの引数が渡されたときに、宣言の型に応じてコンパイル時に(たぶん連続して)メモリに配置されるということです。大きなstructパラメーターは、intパラメーターより多くのスペースを占有します。 doubleはおそらくintより大きいでしょう。呼び出しにはこれらの引数をすべて格納し、インデックスにアクセスまたは変更できるようにする必要があります。型(または少なくとも型のサイズ)を知っていない限り、実行時に引数がどのようにレイアウトされるか把握する方法はありません。
また、メッセージの受け渡しメカニズムは、他のメソッド(objc_msgSend
を呼び出します)(一部のプラットフォームでは、doubleを返すメソッドはobjc_msgSend_fpret
を使用します)から構造体(objc_msgSend_stret
を呼び出します)を返すメソッドでも異なります。前者の場合、構造体は直接返されませんが、書き込む場所は余分なポインタ引数としてoutパラメータとして渡されます。したがって、戻り値の型が分かっていることは、呼び出しでの呼び出しと戻り値の処理にも重要です。
呼び出しを他のオブジェクトに転送しても、最終的にはそのオブジェクト(またはオブジェクトを行末に転送するオブジェクト)は何とかメソッドのシグネチャを知っている必要があります。だからあなたがそれを必要とするセレクタの署名のためにそのオブジェクトを尋ねてみませんか?
異なるタイプのサイズが異なるため、すべてのもので機能する「安全な」署名はありません。