runtime使用二:使用runtime实现方法交换(Method Swizzling)

实际开发过程中,我们可能需要这样的需求: 想要为一个系统方法或者自定义方法加一些判断条件,但是重写系统方法(或自定义方法)再在每个调用的地方修改再费时费力,而且效果不美好,很容易有遗漏等情况
所以这时候我们就需要用到runtime的方法交换,照常调用系统方法或自定义方法,但是运行时实际走的是我们交换了之后的那个方法
现在我们来看他的实现
调用处:

#import "ViewController.h"
#import "NSMutableDictionary+runtime.h"

@interface ViewController ()
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
   
    NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
    NSString *key = nil;
    [dic setObject:@"test" forKey:key];
}

在没有做任何处理的情况下,我们为一个字典设置一个key为空的值,是会崩溃的,但是这里我们做了个方法交换,在调用setObject: forKey: 之前对key值做了判断,以下是方法交换代码


#import "NSMutableDictionary+runtime.h"
#import <objc/runtime.h>

@implementation NSMutableDictionary (runtime)

+ (void)load {

    Method method1 = class_getInstanceMethod(objc_getClass("__NSDictionaryM"), @selector(setObject:forKey:));
    Method method2 =  class_getInstanceMethod(objc_getClass("__NSDictionaryM"), @selector(zsh_setObject:forKey:));
    method_exchangeImplementations(method1, method2);
}

- (void)zsh_setObject:(id)anObject forKey:(id<NSCopying>)aKey {
    
    if (aKey != nil) {
        
        [self zsh_setObject:anObject forKey:aKey];
    } else {
        
        NSLog(@"zhousuhua --- akey不可以为空");
    }
}
@end

运行结果:

zhousuhua --- akey不可以为空

这里的load方法会比main函数还要先调用,由于我们的程序是预加载的,要想load不调用,可以在这里把他删掉在这里插入图片描述
这样load函数就不会执行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值