Method Swizzlingのメソッドレコード
3206 ワード
Method Swizzling , Method Swizzling
一、方法
hook
UIViewController
を例に#import
@implementation UIViewController (Tracking)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
SEL originalSelector = @selector(viewWillAppear:);
SEL swizzledSelector = @selector(xxx_viewWillAppear:);
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
// When swizzling a class method, use the following:
// Class class = object_getClass((id)self);
// ...
// Method originalMethod = class_getClassMethod(class, originalSelector);
// Method swizzledMethod = class_getClassMethod(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);
}
});
}
#pragma mark - Method Swizzling
- (void)xxx_viewWillAppear:(BOOL)animated {
[self xxx_viewWillAppear:animated];
NSLog(@"viewWillAppear: %@", self);
}
@end
上記は一般的な方法であり、hookする
Method
(swizzledMethod
のIMP
)を追加することを試み、追加に成功した場合、swizzledSelector
の実装をoriginalMethod
に置き換えることで、2つの方法で実装された交換が完了する.追加に失敗した場合(すなわち、このclass
に対応するMethod
が既に存在する)、2つのMethod
の実装を直接交換する.UIViewController
のようなviewWillAppear:
メソッドが特定されているクラスでは、もちろんmethod_exchangeImplementations
をサボって直接使用して完成することができますが、上記の方法ではより厳密です.二、+load vs.+initialize
Method Swizzling +load
+initialize
は、クラスのメソッドまたはそのインスタンスが最初に呼び出される前に、+initialize
メソッドが呼び出されるだけです.つまり、呼び出されない可能性があります.+load
メソッドは、main
関数の実行前に呼び出され、各クラス、分類されたload
メソッドが呼び出されます.呼び出されると、すべてのframeworkが実行時にロードされます(ただし、まだロードされていないクラスもあります).1つのクラスのload
メソッドで他のクラスを呼び出すメソッドは、呼び出されたクラスがload
未満の場合、呼び出されたクラスのload
メソッドをトリガーしません.三、dispatch_once
Method Swizziling
が一度だけ行われることを可能な限り保証するために、コードはdispatch_once
に含まれるべきである.四、第三者
GitHubにはAspectのようなサードパーティがあり、
Method Swizzling
メソッドがカプセル化されており、選択コードが元のメソッドの前後で実行されるか、元のメソッドを直接置き換えるなどの他の機能が提供されています.Hookオブジェクト、クラスなど.いくつかのサードパーティ統計も、統計の機能を実現するために同様の方法を使用していることが明らかである.五、参考
Method Swizzling
の使用について詳しく説明しました.load
メソッドの呼び出し順序がcompile source
のファイル順序に関係する