2016-04-19 13 views
1

別のクラスのclass_addMethodを使用してAppDelegateで動的にメソッドを作成した後、呼び出されることはありません。動的に作成されたメソッドが呼び出されない

私は、実行時に作成する方法は次のとおりです。

-(BOOL)application:(UIApplication *)application 
      openURL:(NSURL *)url { 
    //Do something... 
    return YES; 
} 

私は動的に前のメソッドを作成するために使用されるコードは次のとおりです。私のIMP機能とともに

{ 
     UIApplication* app = [[UIApplication sharedApplication] delegate]; 
     class_addMethod([app class], @selector(application:openURL:), (IMP)myMethodIMP, @"[email protected]:"); 
    } 

bool myMethodIMP(id self, SEL _cmd, UIApplication *application, NSURL *url) 
    { 
     [self application: application openURL:url]; 
     //Do something... 
     return YES; 
    } 

私はそれが本当に私のアプリケーションデリゲートにを使用して作成されたことを確認しました方法

私に何かが不足していますか?あなたが正しいです@bbum

+4

をデリゲートが最初に設定されたときにデリゲートがこのメソッドを実装しないため、実装を再度チェックすることは決してないというキャッシングです。一般的に、このパターンで動的に生成するメソッドは、実際には標準的な使用パターンではないため、このような脆弱性が蔓延しています。 – bbum

+0

@bbumそれは意味がありますが、動的にメソッドを生成しながらこれを修正するための回避策がありますか? –

+0

あなたは、上記のメソッドの空の実装(単に 'return YES;')をアプリケーションデリゲートに提供することをお勧めします。そうすれば、UIApplicationがキャッシングに "応答する"ことができれば、それは正しいことです。その後、必要に応じてスウィズルします。 このメソッドでも戻り値があるため、ダミー実装ではデフォルトの戻り値が使用できない可能性があります。最初の呼び出しの前に常に置き換える/オーバーライド/スウィズルする必要があります。 – bbum

答えて

1

、あなたがこの

@interface UIApplication (MBShare) 

@end 

@implementation UIApplication (MBShare) 

+ (void) load 
{ 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 

     SEL originalSelector = @selector(setDelegate:); 
     SEL swizzledSelector = @selector(mb_setDelegate:); 

     Method originalMethod = class_getInstanceMethod(self, originalSelector); 
     Method swizzledMethod = class_getInstanceMethod(self, swizzledSelector); 

     BOOL didAddMethod = 
     class_addMethod(self, 
         originalSelector, 
         method_getImplementation(swizzledMethod), 
         method_getTypeEncoding(swizzledMethod)); 

     if (didAddMethod) { 
      class_replaceMethod(self, 
           swizzledSelector, 
           method_getImplementation(originalMethod), 
           method_getTypeEncoding(originalMethod)); 
     } else { 
      method_exchangeImplementations(originalMethod, swizzledMethod); 
     } 

    }); 
} 

- (void) mb_setDelegate: (id) delegate 
{ 
    //hook method here 
    [[MBShareApi shareInstance] hookAppDelegate: delegate]; 
    [self mb_setDelegate: delegate]; 
} 

@end 

詳細のように行うことができますので、デリゲートが見る、そのメソッドに応答しないdones UIApplicationキャッシュ:それは `UIApplication`であってもよいことhttps://github.com/Baoge2012/MBShare/blob/master/MBShare/MBShareApi.m

関連する問題