美文网首页
iOS - Tips - hook 代理方法

iOS - Tips - hook 代理方法

作者: reboot_q | 来源:发表于2020-04-13 10:46 被阅读0次
    • hook 代理方法入口
    + (void)load {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            Method originMethod = class_getInstanceMethod([self class], @selector(setDelegate:));
            Method newMethod = class_getInstanceMethod([self class], @selector(hook_setDelegate:));
            method_exchangeImplementations(originMethod, newMethod);
        });
    }
    
    • 方法实现
    static void Hook_Method(Class originalClass, SEL originalSel, Class replacedClass, SEL replacedSel, SEL noneSel) {
        Method originalMethod = class_getInstanceMethod(originalClass, originalSel);
        Method replacedMethod = class_getInstanceMethod(replacedClass, replacedSel);
        if (!originalMethod) {
            Method noneMethod = class_getInstanceMethod(replacedClass, noneSel);
            BOOL addNoneMethod = class_addMethod(originalClass, originalSel, method_getImplementation(noneMethod), method_getTypeEncoding(noneMethod));
            if (addNoneMethod) {
                NSLog(@"******** 没有实现 (%@) 方法,手动添加成功!!", NSStringFromSelector(originalSel));
            }
            return;
        }
    
        BOOL addMethod = class_addMethod(originalClass, replacedSel, method_getImplementation(replacedMethod), method_getTypeEncoding(replacedMethod));
        if (addMethod) {
            NSLog(@"******** 实现了 (%@) 方法并成功 Hook 为 --> (%@)", NSStringFromSelector(originalSel), NSStringFromSelector(replacedSel));
            Method newMethod = class_getInstanceMethod(originalClass, replacedSel);
            method_exchangeImplementations(originalMethod, newMethod);
        } else {
            NSLog(@"******** 已替换过,避免多次替换 --> (%@)",NSStringFromClass(originalClass));
        }
    }
    
    • plus
    - (void)hook_setDelegate:(id<UITableViewDelegate>)delegate {
        SEL originalSEL = @selector(tableView:didSelectRowAtIndexPath:);
        SEL newSEL = @selector(hook_tableView:didSelectRowAtIndexPath:);
        
        Hook_Method([delegate class], originalSEL, [self class], newSEL, originalSEL);
        
        [self hook_setDelegate:delegate];
    }
    
    #pragma mark - exchangeMethod
    
    // 代理没有实现方法, 添加实现
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
        NSLog(@"%s", __func__);
    }
    
    // 代理实现了方法, 进行
    - (void)hook_tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
        NSLog(@"%s", __func__);
        [self hook_tableView:tableView didSelectRowAtIndexPath:indexPath];
    }
    

    相关文章

      网友评论

          本文标题:iOS - Tips - hook 代理方法

          本文链接:https://www.haomeiwen.com/subject/bjxgmhtx.html