hook實例函數與類函數的不一樣點。

1、hook實例函數

這個是咱們比較常見的,執行以後,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);

2、hook類函數

實例函數和類函數,主要不一樣點在於class_getInstanceMethodclass_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

相關文章
相關標籤/搜索