在开发中我们经常遇到数组越界造成程序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
网友评论