防止崩溃

2020-10-23  本文已影响0人  夜雨聲煩_

非字典转模型

+ (instancetype)objectWithKeyValues:(NSDictionary *)keyValues
{
    @try {
        if (![keyValues isKindOfClass:[NSDictionary class]]) {
            NSException *exception = [[NSException alloc] initWithName:@"崩溃" reason:@"非字典转模型" userInfo:@{}];
            @throw exception;
        }
    } @catch (NSException *exception) {
        NSLog(@"%@---%@",exception.name,exception.reason);
        return nil;
    } @finally {

    }
    
    id model = [[self alloc] init];
    [model setKeyValues:keyValues];
    return model;
}

数组越界

+ (void)load {
    Class arrayMClass = NSClassFromString(@"__NSArrayM");
    //获取系统的添加元素的方法
    Method addObject = class_getInstanceMethod(arrayMClass, @selector(objectAtIndexedSubscript:));

    //获取我们自定义添加元素的方法
    Method avoidCrash = class_getInstanceMethod(arrayMClass, @selector(avoidCrashobjectAtIndexedSubscript:));

    method_exchangeImplementations(addObject, avoidCrash);
}

- (id)avoidCrashobjectAtIndexedSubscript:(NSUInteger)idx {
    @try {
        if (self.count < idx) {
            NSException *exception = [[NSException alloc] initWithName:@"崩溃" reason:@"数组越界" userInfo:@{}];
            @throw exception;
        }
    }
    @catch (NSException *exception) {
        //你可以在这里进行相应的操作处理
        NSLog(@"%@---%@",exception.name, exception.reason);
        return nil;
    }
    @finally {
    
    }
    return [self avoidCrashobjectAtIndexedSubscript:idx];
}

子线程刷UI

+(void)load
{
    /// hook UIView
    [self bsz_swizzlingClass:[self class] orginalMethod:@selector(setNeedsLayout) customMethod:@selector(bsz_sf_view_setNeedsLayout)];
    [self bsz_swizzlingClass:[self class] orginalMethod:@selector(setNeedsDisplay) customMethod:@selector(bsz_sf_view_setNeedsDisplay)];
    [self bsz_swizzlingClass:[self class] orginalMethod:@selector(setNeedsDisplayInRect:) customMethod:@selector(bsz_sf_view_setNeedsDisplayInRect:)];
}

+ (void)bsz_swizzlingClass:(Class)clazz orginalMethod:(SEL)orginalMethodSelector customMethod:(SEL)customMethodSelector{
    Method systemMethod = class_getInstanceMethod([clazz class], orginalMethodSelector);
    Method swizzMethod = class_getInstanceMethod([clazz class], customMethodSelector);
    method_exchangeImplementations(systemMethod, swizzMethod);
}

- (void)bsz_sf_view_setNeedsLayout
{
    __weak typeof(self) weak_self = self;
    [[MSCServiceQueue sharedInstance] runMainThread:^{
        [weak_self bsz_sf_view_setNeedsLayout];
    }];
}

- (void)bsz_sf_view_setNeedsDisplay
{
    __weak typeof(self) weak_self = self;
    [[MSCServiceQueue sharedInstance] runMainThread:^{
        [weak_self bsz_sf_view_setNeedsDisplay];
    }];
}

- (void)bsz_sf_view_setNeedsDisplayInRect:(CGRect *)rect
{
    __weak typeof(self) weak_self = self;
    [[MSCServiceQueue sharedInstance] runMainThread:^{
        [weak_self bsz_sf_view_setNeedsDisplayInRect:rect];
    }];
}

崩溃日志打印

- (void)application:(UIApplication *)application beforeDidFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
    
    NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);
}

void UncaughtExceptionHandler(NSException *exception)
{
    NSArray *callback = [exception callStackSymbols];
    NSString *reason = [exception reason];
    NSString *name = [exception name];
    NSString *content = [NSString stringWithFormat:@"----异常报告---- name:%@  reason:%@  callStackSymbols:%@",name,reason,[callback componentsJoinedByString:@""]];
    [[MSCVAlert AlertWith:@"闪退" CancelBtn:@"取消" ConfirmBtn:@"确定" Content:content Category:DefaultAlert ResultBolck:^(NSInteger clickIndex) {
    }] show];
    [[NSUserDefaults standardUserDefaults] setObject:content forKey:@"ExceptionContent"];
    [MSCUtils scTrackWithEvent:@"js_error_note" Properties:@{@"error_note":content}];
}
上一篇 下一篇

猜你喜欢

热点阅读