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コード を実現ええ、ここを見ると、ここで呼び出されたのはCの方法ですが、このCの方法はどのように実現されていますか.次の を見てくださいこれは標準的なswizzlingの書き方です.もちろんgithubにもswizzlingに関するオープンソースライブラリがあります.使い勝手もいいです.ここでは は言いません.最初のコードを見て、赤いviewDidAppearは私にhookされる方法です.gbh_tracer_viewDidAppearは私が実現しなければならない方法 です.転載先ですhttp://www.cnblogs.com/n1ckyxu/p/6186850.html ありがとう!!!
(1). Objective-Cでのオブジェクト継承の利用
+ (void)load{
[super load];
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// controller ,
__gbh_tracer_swizzleMethod([self class], @selector(viewDidAppear:), @selector(__gbh_tracer_viewDidAppear:));
});
}
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);
}
}
- (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
}
}