6

Objective-C でオブジェクト用の小さなプラグイン システムを構築したいと考えています。

今、オブジェクトで利用可能なすべての関数にコード行を動的に (実行時に) 追加したいところに行き詰まっています。

ランタイム ライブラリをいじってみましたが、まだ解決策がありません。

これまでに試したことは次のとおりです。

        id (^impyBlock)(id, id, ... ) = ^(id self_, id arguments, ...)
        {
            // My custom code for every function here
            id (*func)(__strong id,SEL,...) = (id (*)(__strong id, SEL, ...))imp;
            return func(obj, s, arguments);

        };

        id (*impyFunct)(id, SEL,...) = imp_implementationWithBlock(impyBlock);
        method_setImplementation(mList[i], impyFunct);

私の問題は、複数の引数がある場合、それらを「func()」に渡す機会がないことです。私の知る限り、これはCでは不可能です。

私が考えたもう1つの解決策は、メソッドのスウィズリングで魔法を行うことです。

手順:

  1. カスタムコードを呼び出し、その後元のメソッドを呼び出す「スウィズルメソッド」を作成します(ネーミングスキーマによって)
  2. 「swizzle Method」のいずれかを使用して、すべての関数の IMP を変更します
  3. 「古い」実装で新しいメソッドを作成し、名前を「___name」のようなスキーマに変更します

このソリューションでは、ポイント 3 で行き詰まっています。完全な新しいメソッドを動的に作成することができませんでした。

上記の問題を解決できる人はいますか、または「すべてのメソッド機能をキャッチする」ための別の解決策がありますか。

最善の方法は、すでに定義されている関数もキャッチする forwardInvocation のようなものです。

ご協力いただきありがとうございます!

4

2 に答える 2

4

あなたの2つの質問の間のつながりを得ることができないので、これを2つの部分に分けてください。

I. 「古い」実装で新しいメソッドを作成し、名前を「___name」のようなスキーマに変更します

それはかなり簡単ですが、それがあなたの問題をどのように解決できるかはわかりません。そのようなメソッドに可変引数関数の引数を渡すことはまだできません (そうです、C ではできません)。

IMP swapImpForSelector(Class cls, SEL sel, IMP newImp)
{
    Method m = class_getInstanceMethod(cls, sel);
    IMP oldImp = method_setImplementation(m, newImp);

    NSString *newSel = [NSString stringWithFormat:@"__prefixed_%@", NSStringFromSelector(sel)];
    const char *type = method_getTypeEncoding(m);
    class_addMethod(cls, NSSelectorFromString(newSel), oldImp, type);

    return oldImp;
}

Ⅱ.関数間で可変引数を渡したい場合は、重いアセンブリ ハックにフォールバックする必要があるかもしれません。幸いなことに、何人かの賢い人がすでにあなたのためにそれを行っています.

NSInvocation クラスを使用するか、それで十分でない場合は、libffiがさらに低レベルになります。

于 2013-06-14T20:50:06.337 に答える