iOS数组越界的保护

先上一段代码

    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实现, 无需导入头文件, 一次添加,对全局工程有效

你可能感兴趣的:(iOS数组越界的保护)