Koichi Adachi

smart phone app development tips

Block構文で記述した処理をインスタンスメソッドとして動的追加し、selectorで受けられるようにする

特定のクラスのインスタンスしか受けられないメソッドを、
新しくクラス定義せずに受けられるようにする方法。
さらにイマイチなことに、呼び出したいメソッドがコールバックにSEL型しか指定できなかったりする。
新しくクラス定義(.hと.m)を追加するのも微妙だったため、
「好きなように書いたblockをインスタンスメソッドとして動的に追加」することで解消してみた。

手順
①コールバック時に処理したい内容をブロック構文で作成
②トリガーとなる処理の中で代理インスタンスを生成
③クラスにメソッドを動的追加
④任意のメソッドに①を渡す

-(void)method1{
    void (^myBlock)(id, NSInteger, NSString *, NSInteger, NSInteger) = ^(id selfInstance, NSInteger value1, NSString *value2, NSInteger value3, NSInteger value4)
    {
        NSLog(@"myBlock : %@", value2);
    };
    
    UIViewController *vc = [[UIViewController alloc] init];
    SEL sel = NSSelectorFromString(@"value1:value2:value3:value4:");
    IMP imp = imp_implementationWithBlock(myBlock);
    class_addMethod([vc class], sel, imp, "vi:*:i:i");
    [AdSDK sendWithViewController:vc callback:sel];
}

init時、vcはセレクタを持っていないが、
AdSDK sendWithViewController:callback:
呼び出しまでの間に動的に加えているためにできる。

詳解 Objective-C 2.0 第3版

詳解 Objective-C 2.0 第3版