+ (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
    }
}

 

posted on 2025-06-05 10:21  懂事长qingzZ  阅读(20)  评论(0)    收藏  举报