数组越界其实是很基本的问题,但是解决起来除了count的判断,还有每个调用的时候都要去判断一遍
对于不明确的数据总会有崩溃的风险
然而 每次调用都判断 那是太累了,runtime&category提供了一个比较简洁的解决方案
首先把NSArray/NSMutableArray的objectAtIndex方法通过objc的runtime 里面method
swizzle把方法进行替换
#import
@interface NSArray
(Category)
@end
#import
"NSArray+Category.h"
#import
@implementation NSArray
(Category)
+(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(safeObjectAtIndex:));
method_exchangeImplementations(oldObjectAtIndex,
newObjectAtIndex);
});
}
-(id)safeObjectAtIndex:(NSInteger)index{
if ( (index > self.count-1)||(index < 0)||!self.count) {
return
nil;
}
return [self
safeObjectAtIndex:index];
}
@end
@interface NSMutableArray
(Category)
@end
@implementation NSMutableArray
(Category)
+(void)load{
[super load];
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//方法交换只要一次就好
//NSMutableArray
Method
mutableObjectAtIndex = class_getInstanceMethod(objc_getClass("__NSArrayM"), @selector(objectAtIndex:));
Method
mutablenewObjectAtIndex = class_getInstanceMethod(objc_getClass("__NSArrayM"), @selector(safeObjectAtIndex:));
method_exchangeImplementations(mutableObjectAtIndex,
mutablenewObjectAtIndex);
});
}
-(id)safeObjectAtIndex:(NSInteger)index{
if ( (index > self.count-1)||(index < 0)||!self.count) {
return
@"越界";
}
return [self
safeObjectAtIndex:index];
}
@end