使用Method Swizzling 方法
swizzling大多时候是在category中的+load方法中使用,也可以创建hook的管理类,放在里面使用。下面例子均在category中进行。
+initialize 方法是在程序调用第一个实例方法/类方法时调用
+load 方法是在初始化时调用
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once (&onceToken, ^{
Class classA = [self class];
SEL originalSelector = @selector (想要替换的实例方法);
SEL swizzledSelector = @selector (替换的新方法名) ;
Method originalMethod = class_getInstanceMethod (classA, originalSelector);
Method swizzlingMethod = class_getInstanceMethod (classA, swizzledSelector);
//如果替换的是类方法
Class classB = Object_getClass ((id) self);
SEL originalSelector = @selector (想要替换的类方法);
SEL swizzledSelector = @selector (替换的新方法名) ;
Method originalMethod = class_getClassMethod (classB, originalSelector);
Method swizzlingMethod = class_getClassMethod (classB, swizzledSelector);
//在交换方法之前要先判断将要替换的方法是否存在
Bool isExist = class_addMethod (classA, originalSelector, method_getImplementation (swizzlingMethod), method_getTypeEncoding (swizzlingMethod));
//实现方法交换
if (isExist) {
class_replaceMethod (classA, swizzledMethod, method_getImplementation (swizzlingMethod), method_getTypeEncode (swizzlingMethod));
} else {
method_exchangeImplementations (originMethod, swizzlingMethod);
}
});
}
category是专门用来添加方法的,如果添加属性系统不会自动生成getter,setter方法,这时需要我们自己手动添加。
1, 在setter方法中:objc_setAssociatedObject
2, 在getter方法中:objc_getAssociatedObject