iOS無コード侵入の方法hook

2734 ワード

*そこで、App側はいくつかのページを切り替えて、インタラクティブな操作の時に統計システムに1本のメッセージを送る必要があります数十個のControllerのプロジェクトの中で、1つ1つコードをプラスするのは完全に不可能で、維持するのも骨が折れるが、ここで処理する必要があるのはControllerで、以下の方法で上述の需要を実現することができます
(1). Objective-Cでのオブジェクト継承の利用
  • 継承はオブジェクト向けの開発で非常によく使われています.私たちが今やっているプロジェクトのように、BaseViewController、
  • があります.
  • 新しく作成されたすべてのViewControllerはBaseView Controllerを継承しています.BaseView Controllerに共通のメソッドを追加することで、サブクラスによって呼び出されます.
  • これは、デルのエンジニアリングにおけるすべてのビューコントローラのスタイルを統一する主な方法です.
  • (2). CategoryとRuntimeによる実行方法hook
  • hookスキームには、コードの侵入を回避し、より広範な汎用性を実現できるという利点がある.swizzlingでは、元のmethodと自分が追加したmethodを結合することができます.つまり、元のエンジニアリングにコードを追加する必要がなく、
  • をグローバルにカバーすることができます.
  • hookスキームを使用する以上runtimeのswizzling
  • を使用します.
  • まずUIViewControllerのcategory
  • を新規作成
  • swizzlingコード
  • を実現
     + (void)load{
        [super load];
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            //  controller  , 
            __gbh_tracer_swizzleMethod([self class], @selector(viewDidAppear:), @selector(__gbh_tracer_viewDidAppear:));
        });
    }
    
  • ええ、ここを見ると、ここで呼び出されたのはCの方法ですが、このCの方法はどのように実現されていますか.次の
  • を見てください
    void __gbh_tracer_swizzleMethod(Class class, SEL originalSelector, SEL swizzledSelector){
        Method originalMethod = class_getInstanceMethod(class, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
        
        BOOL didAddMethod =
        class_addMethod(class,
                        originalSelector,
                        method_getImplementation(swizzledMethod),
                        method_getTypeEncoding(swizzledMethod));
        
        if (didAddMethod) {
            class_replaceMethod(class,
                                swizzledSelector,
                                method_getImplementation(originalMethod),
                                method_getTypeEncoding(originalMethod));
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    }
    
  • これは標準的なswizzlingの書き方です.もちろんgithubにもswizzlingに関するオープンソースライブラリがあります.使い勝手もいいです.ここでは
  • は言いません.
  • 最初のコードを見て、赤いviewDidAppearは私にhookされる方法です.gbh_tracer_viewDidAppearは私が実現しなければならない方法
  • です.
    - (void)__gbh_tracer_viewDidAppear:(BOOL)animated{
        [self __gbh_tracer_viewDidAppear:animated];  // , viewDidAppear: 
        
       // Controller
        NSArray *filter = @[@"UINavigationController",@"UITabBarController"];
        NSString *className = NSStringFromClass(self.class);
        if ([filter containsObject:className]) return ; // Controller log , 
       
        if ([self.title isKindOfClass:[NSString class]] && self.title.length > 0){ // 
            //  log
        }
    
    }
    
  • 転載先ですhttp://www.cnblogs.com/n1ckyxu/p/6186850.html
  • ありがとう!!!