Method Swizzling

2019-01-02  本文已影响11人  相敬如冰

最近在看 《iOS应用逆向与开发》。在4.3.4 runtime的使用中看到了方法交换的写法,不理解 method_exchangeImplementations 就可以完成的事 为什么要加个判断 class_addMethod 是否yes,yes为何class_replaceMethod ,no为何是method_exchangeImplementations,特此搜索了一下 原文链接


我们有没有想过这种情况: " 周全起见,有两种情况要考虑一下。第一种情况是要复写的方法(overridden)并没有在目标类中实现(notimplemented),而是在其父类中实现了。第二种情况是这个方法已经存在于目标类中(does existin the class itself)。这两种情况要区别对待。 (译注: 这个地方有点要明确一下,它的目的是为了使用一个重写的方法替换掉原来的方法。但重写的方法可能是在父类中重写的,也可能是在子类中重写的。) 对于第一种情况,应当先在目标类增加一个新的实现方法(override),然后将复写的方法替换为原先(的实现(original one)。 对于第二情况(在目标类重写的方法)。这时可以通过method_exchangeImplementations来完成交换."

下面是monkeydev作者的源码
#import <objc/runtime.h>

#import "UIViewController+Swizzle.h"

@implementation UIViewController(Swizzle)

+ (void)load {

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        Class class = [self class];

        SEL originalSelector = @selector(viewWillAppear:);

        SEL swizzledSelector = @selector(ms_viewWillAppear:);

        Method originalMethod = class_getInstanceMethod(class, originalSelector);

        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);

        BOOL didAddMethod =

        class_addMethod(class,

                        originalSelector,

                        method_getImplementation(swizzledMethod),

                        method_getTypeEncoding(swizzledMethod));

        if (didAddMethod) {

            class_replaceMethod(class,

                                swizzledSelector,

                                method_getImplementation(originalMethod),

                                method_getTypeEncoding(originalMethod));

        } else {

            method_exchangeImplementations(originalMethod, swizzledMethod);

        }

    });

}

#pragma mark - Method Swizzling

- (void)ms_viewWillAppear:(BOOL)animated {

    [self ms_viewWillAppear:animated];

    NSLog(@"viewWillAppear: %@", self);

}

@end

上一篇下一篇

猜你喜欢

热点阅读