iOS 数组越界,防Crash处理,性能优化 —— HERO博客

常常会看到这样的崩溃日志-[__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


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值