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

本文介绍了一种在实际开发中利用Objective-C的runtime特性进行方法交换的技术,通过在调用前加入判断条件,避免了字典设置空key时的程序崩溃,有效提升了代码的健壮性和安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实际开发过程中,我们可能需要这样的需求: 想要为一个系统方法或者自定义方法加一些判断条件,但是重写系统方法(或自定义方法)再在每个调用的地方修改再费时费力,而且效果不美好,很容易有遗漏等情况
所以这时候我们就需要用到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函数就不会执行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值