Method Swizzling 原理函数
在Objective-C中调用一个方法,实际上是向一个对象发送消息,查找消息的惟一依据是selector的名字。利用Objective-C的动态特性,能够实如今运行时偷换selector对应的方法实现,达到给方法挂钩的目的。指针
每一个类都有一个方法列表,存放着selector的名字和方法实现的映射关系。IMP有点相似函数指针,指向具体的Method实现。code
咱们能够利用 method_exchangeImplementations 来交换2个方法中的IMP,对象
咱们能够利用 class_replaceMethod 来修改类,get
咱们能够利用 method_setImplementation 来直接设置某个方法的IMP,it
……io
归根结底,都是偷换了selector的IMP.class
// // 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
#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