美文网首页iOS开发iOS学习专题
ios规避数组越界、字典空指针等崩溃(一)

ios规避数组越界、字典空指针等崩溃(一)

作者: 世玉茹花 | 来源:发表于2018-12-18 14:25 被阅读1次

    查看bugly,好多崩溃由于莫名原因数组越界或者取超出数组范围内容,亦或set nil for  key 了,针对这些增加几个category来避免直接崩的情况,提升用户体验。

    一、NSArray:

    创建NSArray的扩展类,NSArray+Extension。重写load方法,通过runtime 交换方法来实现。

    +(void)load

    {

        staticdispatch_once_tonceToken;

        dispatch_once(&onceToken, ^{

            // objectindex

            MethodoldObjectAtIndex =class_getInstanceMethod(objc_getClass("__NSArrayI"),@selector(objectAtIndex:));

            MethodnewObjectAtIndex =class_getInstanceMethod(objc_getClass("__NSArrayI"),@selector(objectAtSafeIndex:));

            method_exchangeImplementations(oldObjectAtIndex, newObjectAtIndex);

            // arr[4]

            MethodoldObjectAtIndex1 =class_getInstanceMethod(objc_getClass("__NSArrayI"),@selector(objectAtIndexedSubscript:));

            MethodnewObjectAtIndex1 =  class_getInstanceMethod(objc_getClass("__NSArrayI"),@selector(safeobjectAtIndexedSubscript:));

            method_exchangeImplementations(oldObjectAtIndex1, newObjectAtIndex1);

        });

    }


    因为,数组取值可以用objectindex 和 arr[index]两种方式,所以需要这两种方法都需要替换。

    - (id)objectAtSafeIndex:(NSUInteger)index

    {

        if(index >self.count-1|| !self.count) {

            @try{

                return[selfobjectAtSafeIndex:index];

            }

            @catch(NSException *exception) {

                NSLog(@"exception: %@", exception.reason);

                returnnil;

            }

        }else{

            return[selfobjectAtSafeIndex:index];

        }

    }

    - (instancetype)safeobjectAtIndexedSubscript:(NSUInteger)index{

        if(index > (self.count-1)) {// 数组越界

            returnnil;

        }else{// 没有越界

            return [self safeobjectAtIndexedSubscript:index];

        }

    }


    二、NSMutableArray+Extension。。。同理,可变数组如下:

    +(void)load  //第一次加载内存的时候会自动调用。

    {

        staticdispatch_once_tonceToken;

        dispatch_once(&onceToken, ^{

            //addObject

            MethodorginalMethod =class_getInstanceMethod(NSClassFromString(@"__NSArrayM"),@selector(addObject:));

            MethodnewMethod =class_getInstanceMethod(NSClassFromString(@"__NSArrayM"),@selector(gp_addobjc:));

            method_exchangeImplementations(orginalMethod, newMethod);

            //替换objectAtIndex方法

            MethodoldMutableObjectAtIndex =class_getInstanceMethod(objc_getClass("__NSArrayM"),@selector(objectAtIndex:));

            MethodnewMutableObjectAtIndex =  class_getInstanceMethod(objc_getClass("__NSArrayM"),@selector(mutableObjectAtSafeIndex:));

            method_exchangeImplementations(oldMutableObjectAtIndex, newMutableObjectAtIndex);

            //替换arr[4]方法

            MethodoldMutableObjectAtIndex1 =class_getInstanceMethod(objc_getClass("__NSArrayM"),@selector(objectAtIndexedSubscript:));

            MethodnewMutableObjectAtIndex1 =  class_getInstanceMethod(objc_getClass("__NSArrayM"),@selector(safeobjectAtIndexedSubscript:));

            method_exchangeImplementations(oldMutableObjectAtIndex1, newMutableObjectAtIndex1);

        });

    }

    //addobject

    -(void)gp_addobjc:(id)object

    {

        if(object !=nil) {

            [self gp_addobjc:object];//此时  方法交换,所以不能在这写addobject。若这样的话,会造成死循环。

        }

    }

    //objectAtIndex

    - (id)mutableObjectAtSafeIndex:(NSUInteger)index

    {

        if(index >self.count-1|| !self.count) {

            @try{

                return [self mutableObjectAtSafeIndex:index];

            }

            @catch(NSException *exception) {

                NSLog(@"exception: %@", exception.reason);

                returnnil;

            }

        }else{

            return [self mutableObjectAtSafeIndex:index];

        }

    }

    //aar[index]

    - (instancetype)safeobjectAtIndexedSubscript:(NSUInteger)index{

        if(index > (self.count-1)) {// 数组越界

            returnnil;

        }else{// 没有越界

            return [self safeobjectAtIndexedSubscript:index];

        }

    }

    相关文章

      网友评论

        本文标题:ios规避数组越界、字典空指针等崩溃(一)

        本文链接:https://www.haomeiwen.com/subject/zzxlkqtx.html