+ (void)initialize { if (self == [MyViewController class]) { // 获取原始方法和替代方法 Method originalMethod = class_getInstanceMethod([self class], @selector(viewDidLoad)); Method swizzledMethod = class_getInstanceMethod([self class], @selector(xxx_viewDidLoad)); // 执行方法交换 method_exchangeImplementations(originalMethod, swizzledMethod); } } // 新的 viewDidLoad 实现 - (void)xxx_viewDidLoad { // 在原始 viewDidLoad 之前执行你自定义的行为 NSLog(@"viewDidLoad is called"); // 调用原始 viewDidLoad(因为方法交换了,实际上是调用原来的 viewDidLoad) [self xxx_viewDidLoad]; }
OC版本
+ (void)hookClass:(Class)cls originalSelector:(SEL)orlSelector swizzledSelector:(SEL)swzdSelector { Method originalMethod = class_getInstanceMethod(cls, orlSelector); Method swizzledMethod = class_getInstanceMethod(cls, swzdSelector); if (class_addMethod(self, orlSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))) { class_replaceMethod(self, swzdSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); } else { method_exchangeImplementations(originalMethod, swizzledMethod); } }
OC版应用实例方法替换 用自己的zf_dealloc 替换系统的dealloc
+ (void)initialize { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ SEL selectors[] = { NSSelectorFromString(@"dealloc") }; for (NSInteger index = 0; index < sizeof(selectors) / sizeof(SEL); ++index) { SEL originalSelector = selectors[index]; SEL swizzledSelector = NSSelectorFromString([@"zf_" stringByAppendingString:NSStringFromSelector(originalSelector)]); Method originalMethod = class_getInstanceMethod(self, originalSelector); Method swizzledMethod = class_getInstanceMethod(self, swizzledSelector); if (class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))) { class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); } else { method_exchangeImplementations(originalMethod, swizzledMethod); } } }); } - (void)zf_dealloc { [self.smallFloatView removeFromSuperview]; self.smallFloatView = nil; [self zf_dealloc]; }
Swift版本
// MARK: - 三、Hook @objc public extension NSObject { /// 实例方法替换 static func hookInstanceMethod(of origSel: Selector, with replSel: Selector) -> Bool { let clz: AnyClass = classForCoder() guard let oriMethod = class_getInstanceMethod(clz, origSel) as Method? else { JKPrint("原 实例方法:Swizzling Method(\(origSel)) not found while swizzling class \(NSStringFromClass(classForCoder())).") return false } guard let repMethod = class_getInstanceMethod(clz, replSel) as Method? else { JKPrint("新 实例方法:Swizzling Method(\(replSel)) not found while swizzling class \(NSStringFromClass(classForCoder())).") return false } // 在进行 Swizzling 的时候,需要用 class_addMethod 先进行判断一下原有类中是否有要替换方法的实现 let didAddMethod: Bool = class_addMethod(clz, origSel, method_getImplementation(repMethod), method_getTypeEncoding(repMethod)) // 如果 class_addMethod 返回 yes,说明当前类中没有要替换方法的实现,所以需要在父类中查找,这时候就用到 method_getImplemetation 去获取 class_getInstanceMethod 里面的方法实现,然后再进行 class_replaceMethod 来实现 Swizzing if didAddMethod { class_replaceMethod(clz, replSel, method_getImplementation(oriMethod), method_getTypeEncoding(oriMethod)) } else { method_exchangeImplementations(oriMethod, repMethod) } return true } /// 类方法替换 static func hookClassMethod(of origSel: Selector, with replSel: Selector) -> Bool { let clz: AnyClass = classForCoder() guard let oriMethod = class_getClassMethod(clz, origSel) as Method? else { JKPrint("原 类方法:Swizzling Method(\(origSel)) not found while swizzling class \(NSStringFromClass(classForCoder())).") return false } guard let repMethod = class_getClassMethod(clz, replSel) as Method? else { JKPrint("新 类方法 replSel:Swizzling Method(\(replSel)) not found while swizzling class \(NSStringFromClass(classForCoder())).") return false } // 在进行 Swizzling 的时候,需要用 class_addMethod 先进行判断一下原有类中是否有要替换方法的实现 let didAddMethod: Bool = class_addMethod(clz, origSel, method_getImplementation(repMethod), method_getTypeEncoding(repMethod)) // 如果 class_addMethod 返回 yes,说明当前类中没有要替换方法的实现,所以需要在父类中查找,这时候就用到 method_getImplemetation 去获取 class_getInstanceMethod 里面的方法实现,然后再进行 class_replaceMethod 来实现 Swizzing if didAddMethod { class_replaceMethod(clz, replSel, method_getImplementation(oriMethod), method_getTypeEncoding(oriMethod)) } else { method_exchangeImplementations(oriMethod, repMethod) } return true } /// 方法替换 static func hookMethod(of origSel: Selector, with replSel: Selector, isClassMethod: Bool) -> Bool { let clz: AnyClass = classForCoder() guard let oriMethod = (isClassMethod ? class_getClassMethod(clz, origSel) : class_getClassMethod(clz, origSel)) as Method?, let repMethod = (isClassMethod ? class_getClassMethod(clz, replSel) : class_getClassMethod(clz, replSel)) as Method? else { JKPrint("Swizzling Method(s) not found while swizzling class \(NSStringFromClass(classForCoder())).") return false } // 在进行 Swizzling 的时候,需要用 class_addMethod 先进行判断一下原有类中是否有要替换方法的实现 let didAddMethod: Bool = class_addMethod(clz, origSel, method_getImplementation(repMethod), method_getTypeEncoding(repMethod)) // 如果 class_addMethod 返回 yes,说明当前类中没有要替换方法的实现,所以需要在父类中查找,这时候就用到 method_getImplemetation 去获取 class_getInstanceMethod 里面的方法实现,然后再进行 class_replaceMethod 来实现 Swizzing if didAddMethod { class_replaceMethod(clz, replSel, method_getImplementation(oriMethod), method_getTypeEncoding(oriMethod)) } else { method_exchangeImplementations(oriMethod, repMethod) } return true } }
浙公网安备 33010602011771号