Runtime处理数组越界

2017-05-11  本文已影响0人  Erica0708

在开发中我们经常遇到数组越界造成程序crash,我们可以选择在使用数组时添加判断,但是这种方法比较麻烦,因为你项目中如果用到一百个数组,你就要添加一百次判断,这是最愚笨的方法,或者有的同学会使用下面这种方法

//建一个NSArray的分类,在分类里写入下面方法

- (id)objectAtIndexCheck:(NSUInteger)index{
    
    if (index>self.count-1) {
        NSAssert(NO, @"index beyond the boundary");
        return nil;
    }else{
        return [self objectAtIndex:index];
    }
}

使用

 NSArray *array = @[@"1",@"2",@"3"];
 NSLog(@"-------%@--",[array objectAtIndexCheck:4]);

这个方法有一个缺点就是直接用下标取值是一样会crash

如果是用runtime处理此种问题,不管你用objectAtIndex或者直接用下标array[4]都不会出现问题
#import "NSArray+Bundary.h"
#import <objc/runtime.h>
@implementation NSArray (Bundary)
+ (void)load
{
    //使用单例模式
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    //方法的selector用于表示运行时方法的名字。
    //Objective-C在编译时,会依据每一个方法的名字、参数序列,生成一个唯一的整型标识(Int类型的地址),这个标识就是SEL
        SEL newSel = @selector(newObjectAtIndex:);
        SEL originalSel = @selector(objectAtIndex:);
        //使用runtime方法拿到实例中的方法
        Method newMethod = class_getInstanceMethod(self, newSel);
        Method originalMethod = class_getInstanceMethod(self, originalSel);
        
        //交换方法
        method_exchangeImplementations(originalMethod, newMethod);
    });
}
- (id)newObjectAtIndex:(NSUInteger)index{
   
    if (index > self.count-1) {
        NSAssert(NO, @"index beyond the boundary");
        return nil;
    }else{
        return [self newObjectAtIndex:index];
    }
}
@end

使用

NSArray *array = @[@"1",@"2",@"3"];
    
NSLog(@"%@",array[4]);

这段代码主要是运用到runtime的方法交换函数,让系统自带的objectAtIndex方法和自己定义的newObjectAtIndex方法交换,然后再newObjectAtIndex方法里面处理判断是否越界
[self newObjectAtIndex:index]这个方法不会循环调用,因为我们已经将objectAtIndex替换为newObjectAtIndex

上一篇下一篇

猜你喜欢

热点阅读