runtime/runloop/多线程

iOS-Runtime方法交换

2016-06-25  本文已影响673人  FlyElephant

iOS开发中需要在原有的方法之后执行新的方法,如果我们想在UIController中的viewWillAppear之后执行其他的操作,或者说需要重写原有的设置颜色,位置等操作,都可以通过方法交换实现,实际操作也很简单,通过分类方法中的load方法实现:
<pre><code>`
@implementation UIViewController (FlyElephant)

+(void)load{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];

    SEL originalSelector = @selector(viewWillAppear:);
    SEL swizzledSelector = @selector(fe_viewWillApper:);
    
    Method originalMethod = class_getInstanceMethod(class, originalSelector);
    Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
    
    BOOL success = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
    if (success) {
        class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
    } else {
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
});

}

-(void)fe_viewWillApper:(BOOL)animated{
NSLog(@"FlyElephant--fe_viewWillApper");
}

@end`</code></pre>

FlyElephant.png

方法交换的时候有两点是需要注意的:
1.如果原有的父类中是没有定义的原始方法,那么originalSelector没有对应的执行方法,所以我们需要通过class_method将替换方法实现给originalSelector,看到网上有人没有判断直接进行交换是不正确的实现;
2.如果originalSelector对应的有执行,简单替换即可;

如果对iOS方面有技术问题可以加入228407086群与我交流~

上一篇下一篇

猜你喜欢

热点阅读