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
来源:oschina
链接:https://my.oschina.net/u/2370932/blog/538724