灵活运用runtime改写系统的方法

            iOS系统的一些方法的实现效果不尽人意,例如数组越界苹果就会直接crash,不会像字典一样置空,程序就会闪退,用户体验会很不好。有些时候数组越界了,但我们不想让程序崩溃。越界了,就置空,程序还能正常运行。那么如何避免数组越界引起的程序崩溃?改写NSArray的objectAtIndex方法,然后在里面写一些自己的操作,但是我们并不知道系统的objectAtIndex是如何实现的。

            整理一下思路:我们要在调用NSArray的objectAtIndex方法的时候,让它调用不是系统的objectAtIndex方法而是一个我们自己写的方法。也就是说交换方法,用到runtime。

一、首先,我们创建一个“判空”功能的NSArray的类别(关于类别,请看前面的博文),如:NSArray+JDNil.h。之后导入runtime头文件:#import "objc/runtime.h"

二、然后,我们在NSArray类的加载方法load里面交换方法。如下:

+ (void)load {
    [super load];
    Method fromMethod = class_getInstanceMethod(objc_getClass("__NSArrayI"), @selector(objectAtIndex:));
    Method toMethod = class_getInstanceMethod(objc_getClass("__NSArrayI"), @selector(xxf_objectAtIndex:));
    method_exchangeImplementations(fromMethod, toMethod);
}

           这三句话的意思是,获得__NSArrayI类的objectAtIndex方法和xxf_objectAtIndex方法,并把两者交换。交换之后,当调用objectAtIndex方法时,执行的是xxf_objectAtIndex里面的代码。

           需要注意的有两点:

1.load方法,类的加载方法。实验证明工程启动后就会自动调用load方法,不管有没有引用头文件。最先调用,不需要引入头文件。

2.注意是__NSArrayI而不是NSArray,__NSArrayI才是真身,例如下面的数组越界崩溃信息中的[__NSArrayI objectAtIndex:]

*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 3 beyond bounds [0 .. 2]'


三、实现xxf_objectAtIndex方法。如下:

- (id)xxf_objectAtIndex:(NSUInteger)index {
    if (self.count-1 < index) {
        return nil;
    } else {
        return [self xxf_objectAtIndex:index];
    }
}

参考博文: iOS黑魔法-Method Swizzling








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值