這個是咱們比較常見的,執行以後,test1函數就指向hooktest1了函數
Class originalClass = objc_getClass("ViewControllerA"); SEL originalSelector = @selector(test1); SEL swizzledSelector = @selector(hooktest1); // 若originalClass已經存在test1方法,則返回NO Method originalMethod = class_getInstanceMethod(originalClass, originalSelector); Method swizzledMethod = class_getInstanceMethod(originalClass, swizzledSelector); BOOL didAddMethod = class_addMethod(originalClass,originalSelector,method_getImplementation(swizzledMethod),method_getTypeEncoding(swizzledMethod)); // 若原來的方法並不存在,則添加便可 if (didAddMethod) { class_replaceMethod(originalClass,swizzledSelector,method_getImplementation(originalMethod),method_getTypeEncoding(originalMethod)); } method_exchangeImplementations(originalMethod, swizzledMethod);
有一個問題,上面的作法是hook這個類的A函數指向B函數,如何hook這個類的A函數指向另外一個類的B函數呢?代碼修改以下code
Class originalClass = objc_getClass("ViewControllerA"); Class swizzledClass = objc_getClass("ViewControllerB"); SEL originalSelector = @selector(test1); SEL swizzledSelector = @selector(hooktest1); // 若originalClass已經存在test1方法,則返回NO Method originalMethod = class_getInstanceMethod(originalClass, originalSelector); Method swizzledMethod = class_getInstanceMethod(swizzledClass, swizzledSelector); BOOL didAddMethod = class_addMethod(swizzledClass,originalSelector,method_getImplementation(swizzledMethod),method_getTypeEncoding(swizzledMethod)); // 若原來的方法並不存在,則添加便可 if (didAddMethod) { class_replaceMethod(originalClass,swizzledSelector,method_getImplementation(originalMethod),method_getTypeEncoding(originalMethod)); } method_exchangeImplementations(originalMethod, swizzledMethod);
實例函數和類函數,主要不一樣點在於class_getInstanceMethod
和class_getClassMethod
,下面是hook類函數的寫法。get
Class originalClass = objc_getClass("ViewControllerA"); Class swizzledClass = objc_getClass("ViewControllerB"); SEL originalSelector = @selector(test2); SEL swizzledSelector = @selector(hooktest2); // 若originalClass已經存在test2方法,則返回NO Method originalMethod = class_getClassMethod(originalClass, originalSelector); Method swizzledMethod = class_getClassMethod(swizzledClass, swizzledSelector); BOOL didAddMethod = class_addMethod(swizzledClass,originalSelector,method_getImplementation(swizzledMethod),method_getTypeEncoding(swizzledMethod)); // 若原來的方法並不存在,則添加便可 if (didAddMethod) { class_replaceMethod(originalClass,swizzledSelector,method_getImplementation(originalMethod),method_getTypeEncoding(originalMethod)); } method_exchangeImplementations(originalMethod, swizzledMethod);
還有一個不一樣點,就是在不一樣類的狀況下,hook以後的函數,若是要調用原函數,實例函數的,只須要以下io
- (void)hooktest1 { [self hooktest1]; }
可是,hook以後的類函數,須要這樣調用原函數class
+ (void)hooktest2 { [objc_getClass("ViewControllerB") hooktest2]; }
基本上就這些了,用的好就很方便了。test