iOS 数组越界,防Crash处理性能优化

释放双眼,带上耳机,听听看~!

常常会看到这样的崩溃日志-[__NSArrayM objectAtIndex:]: index4 beyond bounds
[0 ..1],数组越界。

举个列子:

    int index = 3;
NSArray *array = @[@"z", @"x", @"c"];
[array objectAtIndex:index];

这段代码执行会崩溃,数组越界,解决办法有很多,比如我们可以尝试增加一个条件判断:

    int index = 3;
NSArray *array = @[@"z", @"x", @"c"];
if (index < array.count) {
[array objectAtIndex:index];
}

或者使用try…catch捕获异常:

    int index = 3;
NSArray *array = @[@"z", @"x", @"c"];
@try {
//可能抛出异常的代码
[array objectAtIndex:index];
}
@catch (NSException *exception) {
//处理异常
NSLog(@"exception: %@", exception.reason);
}
@finally {
//finally代码块是可选的,如果写了,不管有没有异常,block内的代码都会被执行
NSLog(@"finally");
}

 

上面方法已经可以避免crash,为了避免冗余的代码,写一个NSArray的分类,利用runtime替换NSArray的对象方法objectAtIndex:,在这里进行判断,捕获异常:

#import <Foundation/Foundation.h>
@interface NSArray (Crash)
@end
/*** ---------------分割线--------------- ***/
#import "NSArray+Crash.h"
#import <objc/runtime.h>
@implementation NSArray (Crash)
+ (void)load
{
[super load];
//替换不可变数组方法
Method oldObjectAtIndex = class_getInstanceMethod(objc_getClass("__NSArrayI"), @selector(objectAtIndex:));
Method newObjectAtIndex = class_getInstanceMethod(objc_getClass("__NSArrayI"), @selector(objectAtSafeIndex:));
method_exchangeImplementations(oldObjectAtIndex, newObjectAtIndex);
//替换可变数组方法
Method oldMutableObjectAtIndex = class_getInstanceMethod(objc_getClass("__NSArrayM"), @selector(objectAtIndex:));
Method newMutableObjectAtIndex =  class_getInstanceMethod(objc_getClass("__NSArrayM"), @selector(mutableObjectAtSafeIndex:));
method_exchangeImplementations(oldMutableObjectAtIndex, newMutableObjectAtIndex);
}
- (id)objectAtSafeIndex:(NSUInteger)index
{
if (index > self.count - 1 || !self.count) {
@try {
return [self objectAtSafeIndex:index];
}
@catch (NSException *exception) {
NSLog(@"exception: %@", exception.reason);
return nil;
}
}else {
return [self objectAtSafeIndex:index];
}
}
- (id)mutableObjectAtSafeIndex:(NSUInteger)index
{
if (index > self.count - 1 || !self.count) {
@try {
return [self mutableObjectAtSafeIndex:index];
}
@catch (NSException *exception) {
NSLog(@"exception: %@", exception.reason);
return nil;
}
}else {
return [self mutableObjectAtSafeIndex:index];
}
}
@end

 

人已赞赏
iOS文章

iOS开发runtime实战应用:关联对象

2020-1-20 17:13:44

iOS文章

Xcode 10+ 不支持使用lbstdc++插件报错异常解决方案

2020-1-20 20:06:45

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
有新消息 消息中心
搜索