iOS防止闪退处理,防止Crash

作者: 小江9527 | 来源:发表于2019-04-02 17:04 被阅读298次

    由于之前做项目的时候,时不时会有无法预见的错误,导致App上线了,Crash的时候,用户体验非常不好。查过各方面的资料后,决定把这些无法预见的Crash给解决的,至少先保证App能正常用。

    想了下,其实也不难,就是对NSString、NSMutableString、NSArray、NSMutableArray、NSDictionary、NSMutableDictionary、KVO 这些常用的类方法做了方法替换,数组索引越界、字典数据对象为nil的异常处理

    @implementation NSArray (GJNoCrash)
    void array_method_exchangeImplementations(Class cls, SEL name, SEL name2) {
        
        Method fromMethod = class_getInstanceMethod(cls, name);
        Method toMethod = class_getInstanceMethod(cls, name2);
        method_exchangeImplementations(fromMethod, toMethod);
    }
    
    + (void)load
    {
        Class __NSArray     = objc_getClass("NSArray");
        Class __NSArrayI    = objc_getClass("__NSArrayI");
        Class __NSArray0    = objc_getClass("__NSArray0");
        Class __NSSingleObjectArrayI = objc_getClass("__NSSingleObjectArrayI");
        
        array_method_exchangeImplementations(__NSArray, @selector(arrayWithObjects:count:), @selector(safeArrayWithObjects:count:));
        array_method_exchangeImplementations(__NSArray, @selector(objectsAtIndexes:), @selector(safeObjectsAtIndexes:));
        array_method_exchangeImplementations(__NSArrayI, @selector(objectAtIndexedSubscript:), @selector(safeObjectAtIndexedSubscript:));
        array_method_exchangeImplementations(__NSArray0, @selector(objectAtIndex:), @selector(safeObjectAtIndexedNullarray:));
        array_method_exchangeImplementations(__NSSingleObjectArrayI, @selector(objectAtIndex:), @selector(safeObjectAtIndexedArrayCountOnlyOne:));
        
        array_method_exchangeImplementations(__NSArray, @selector(getObjects:range:), @selector(safeGetObjectsArray:range:));
        array_method_exchangeImplementations(__NSArrayI, @selector(getObjects:range:), @selector(safeGetObjectsArrayI:range:));
        array_method_exchangeImplementations(__NSSingleObjectArrayI, @selector(getObjects:range:), @selector(safeGetObjectsNSSingleObjectArrayI:range:));
        
    }
    
    - (instancetype)safeArrayWithObjects:(const id  _Nonnull __unsafe_unretained *)objects count:(NSUInteger)cnt
    {
        id instance = nil;
        
        @try {
            instance = [self safeArrayWithObjects:objects count:cnt];
        }
        @catch (NSException *exception) {
            
            //以下是对错误数据的处理,把为nil的数据去掉,然后初始化数组
            NSInteger newObjsIndex = 0;
            id  _Nonnull __unsafe_unretained newObjects[cnt];
            
            for (int i = 0; i < cnt; i++) {
                if (objects[i] != nil) {
                    newObjects[newObjsIndex] = objects[i];
                    newObjsIndex++;
                }
            }
            instance = [self safeArrayWithObjects:newObjects count:newObjsIndex];
        }
        @finally {
            return instance;
        }
    }
    @end
    

    大概原理就是这样

    常见异常

    NSString *s = @"aa";
    NSString *ss = [s substringFromIndex:10];
    NSLog(@"ss:%@", ss);
            
    NSMutableString *s = [NSMutableString stringWithFormat:@"aaaa"];
    NSString *ss = [s stringByReplacingCharactersInRange:NSMakeRange(10, 10) withString:@"bb"];
    NSLog(@"ss:%@", ss);
            
    NSArray *a = [NSArray array];
    id v = [a objectAtIndex:10];
    NSLog(@"array index 10 :%@", v);
            
    NSMutableArray *array = [NSMutableArray array];
    [array addObject:nil];
    NSLog(@"NSMutableArray:%@", array);
            
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    [dict setObject:nil forKey:@"key1"];
    [dict setObject:@"value1" forKey:nil];
    [dict setObject:@"value2" forKey:@"key2"];
    NSLog(@"NSMutableDictionary:%@", dict);
    

    我把这些整合发布到pod上去了。

    pod search GJNoCrash
    

    Crash log 处理有两种方式

    
    #import "GJCrashLog.h"
    //方法1 block方法
    [[GJCrashLog manager] callbackCrashLog:^(NSString *crashLog) {
              //处理crashlog
    }];
    
    //方法2 delegate方式
    [GJCrashLog manager].delegate = self;
    //GJCrashLog Delegate
    -(void)callbackGJCrashLog:(NSString *)crashLog
    {
        //处理crashlog
    }
    

    github地址在这里

    相关文章

      网友评论

        本文标题:iOS防止闪退处理,防止Crash

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