Method Swizzling利用OC动态性解决问题

Method Swizzling 原理

在Objective-C中调用一个方法,其实是向一个对象发送消息,查找消息的唯一依据是selector的名字。利用Objective-C的动态特性,可以实现在运行时偷换selector对应的方法实现,达到给方法挂钩的目的。

每个类都有一个方法列表,存放着selector的名字和方法实现的映射关系。IMP有点类似函数指针,指向具体的Method实现。

我们可以利用 method_exchangeImplementations 来交换2个方法中的IMP,

我们可以利用 class_replaceMethod 来修改类,

我们可以利用 method_setImplementation 来直接设置某个方法的IMP,

……

归根结底,都是偷换了selector的IMP.

//
//  MRProgressOverlayView+runtime.m
//  Identify
//
//  Created by wupeng on 15/12/3.
//  Copyright © 2015年 StarShine. All rights reserved.
//

#import "MRProgressOverlayView+runtime.h"
#import <objc/runtime.h>
#import "StringUtils.h"
#import "NSObject+WPSwizzle.h"
@implementation MRProgressOverlayView (runtime)
//在合适的位置调用替换方法,重写load
+(void)load {
    [self swizzleClassSelector:@selector(showOverlayAddedTo:animated:) withNewSelector:@selector(showLoadingAddedTo:animated:)];
}
//替换的新方法。即实现
+(instancetype)showLoadingAddedTo:(UIView *)view animated:(BOOL)animated {
    MRProgressOverlayView *overLayView =  [MRProgressOverlayView showOverlayAddedTo:view title:[StringUtils getString:@"Loading"] mode:MRProgressOverlayViewModeIndeterminate animated:YES];
    overLayView.tintColor = [UIColor colorWithRed:228.f/255.f green:173.f/255.f blue:3.f/255.f alpha:1.f];
    return overLayView;
}
@end

Method Swizzling 的封装

#import "NSObject+WPSwizzle.h"
#import <objc/runtime.h>
@implementation NSObject (WPSwizzle)
//替换对象方法
+ (void)swizzleInstanceSelector:(SEL)origSelector withNewSelector:(SEL)newSelector{
    Method method1 = class_getInstanceMethod([self class], origSelector);
    Method method2 = class_getInstanceMethod([self class], newSelector);
    method_exchangeImplementations(method1, method2);
}
//替换类方法
+ (void)swizzleClassSelector:(SEL)origSelector withNewSelector:(SEL)newSelector{
    Method method1 = class_getClassMethod([self class], origSelector);
    Method method2 = class_getClassMethod([self class], newSelector);
    method_exchangeImplementations(method1, method2);
}
@end


你可能感兴趣的:(Method Swizzling利用OC动态性解决问题)