先上一段代码
NSArray *testArray = @[@"a",@"b",@"c"];
NSLog(@"%@",[testArray objectAtIndex:3]);
NSLog(@"%@",testArray[3]);
在iOS中, 上述两种取数组元素的方法都会导致程序崩溃, 称为"数组越界", 那么在日常开发中,因为数据的不确定性, 如果每次取指定index的元素前都要对数组的count进行判断,会非常繁琐, 也会增加代码量.
这里介绍一种简单的全局方法, 是通过tuntime的method swizzling实现的:
为NSArray添加一个category
#import
///对数组越界进行保护
// 适用于 objectAtIndex 的保护 ,对 array[index] 无效
// runtime实现, 无需导入头文件
@interface NSArray (DHArraySafe)
@end
#import "NSArray+ DHArraySafe.h"
#import
@implementation NSArray (DHArraySafe)
+ (void)load{
[super load];
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{ //方法交换只要一次就好
Method oldObjectAtIndex = class_getInstanceMethod(objc_getClass("__NSArrayI"), @selector(objectAtIndex:));
Method newObjectAtIndex = class_getInstanceMethod(objc_getClass("__NSArrayI"), @selector(__nickyTsui__objectAtIndex:));
method_exchangeImplementations(oldObjectAtIndex, newObjectAtIndex);
});
}
- (id)__nickyTsui__objectAtIndex:(NSUInteger)index{
if (index > self.count - 1 || !self.count){
@try {
return [self __nickyTsui__objectAtIndex:index];
} @catch (NSException *exception) {
//__throwOutException 抛出异常
return nil;
} @finally {
}
}
else{
return [self __nickyTsui__objectAtIndex:index];
}
}
@end
//mutableArray的对象也需要做方法交换
@interface NSMutableArray (DHArraySafe)
@end
@implementation NSMutableArray (DHArraySafe)
+ (void)load{
[super load];
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{ //方法交换只要一次就好
Method oldObjectAtIndex = class_getInstanceMethod(objc_getClass("__NSArrayM"), @selector(objectAtIndex:));
Method newObjectAtIndex = class_getInstanceMethod(objc_getClass("__NSArrayM"), @selector(__nickyTsui__objectAtIndex:));
method_exchangeImplementations(oldObjectAtIndex, newObjectAtIndex);
});
}
- (id)__nickyTsui__objectAtIndex:(NSUInteger)index{
if (index > self.count - 1 || !self.count){
@try {
return [self __nickyTsui__objectAtIndex:index];
} @catch (NSException *exception) {
//__throwOutException 抛出异常
return nil;
} @finally {
}
}
else{
return [self __nickyTsui__objectAtIndex:index];
}
}
@end
注意:
1.对数组越界进行保护
2.适用于 objectAtIndex 的保护 ,对 array[index] 无效
3.runtime实现, 无需导入头文件, 一次添加,对全局工程有效