Method Swizzling利用OC動態性解決問題

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
相關文章
相關標籤/搜索