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