1、故意写一个相关崩溃代码
//拦截1
NSMutableArray *arr1 = @[@"1"].mutableCopy;
[arr1 replaceObjectAtIndex:5 withObject:@"2"];
//拦截2
NSMutableArray *arr2 = @[].mutableCopy;
[arr2 replaceObjectAtIndex:5 withObject:@"1"];
//拦截3
NSMutableArray *arr3 = @[@"1", @"2"].mutableCopy;
[arr3 replaceObjectAtIndex:0 withObject:nil];
2、方法交换拦截
#import "NSMutableArray+HuAvoidCrash.h"
#import <objc/message.h>
@implementation NSMutableArray (HuAvoidCrash)
+(void)load{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = NSClassFromString(@"__NSArrayM");
Method old = class_getInstanceMethod(class, @selector(replaceObjectAtIndex:withObject:));
Method new = class_getInstanceMethod(class, @selector(hu_replaceObjectAtIndex:withObject:));
if (old && new) {
method_exchangeImplementations(old, new);
}
});
}
-(void)hu_replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject{
if (self.count-1 >= index && anObject) {
[self hu_replaceObjectAtIndex:index withObject:anObject];
}else{
}
}
@end
3、运行结果
发现拦截1成功,但是拦截2无效,最终奔溃。(但是也走进了这个拦截方法)

4、原因
看下图:断点走进了33行;导致崩溃
但是self确实0个元素;index是5;

为什么呢?

因为:NSUInteger的问题,NSUInteger是无符号的,没有负数
5、解决方案:
-(void)hu_replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject{
if (self.count > index && anObject) {
[self hu_replaceObjectAtIndex:index withObject:anObject];
}else{
}
}
网友评论