zoukankan      html  css  js  c++  java
  • App崩溃前上传数据或者操作UI iOS

    iOS应用崩溃,常见的崩溃信息有 EXC_BAD_ACCESS 、 SIGABRT XXXXXXX ,而这里分为两种情况,一种是未被捕获的异常,我们只需要添加一个回调函数,并在应用启动时调用一个 API即可; 另

    一种是直接发送的 SIGABRT XXXXXXX ,这里我们也需要监听各种信号,然后添加回调函数。

    针对情况一,其实我们都见过。 我们在收集App崩溃信息时,需要添加一个函数 NSSetUncaughtExceptionHandler(&HandleException) ,参数 是一个回调函数,在回调函数里获取到异常的

    原因,当前的堆栈信息等保存到 dump文件,然后供下次打开App时上传到服务器。

    其实,我们在HandleException回调函数中,可以获取到当前的RunLoop,然后获取该RunLoop中的所有Mode,手动运行一遍。

    针对情况二,首先针对多种要捕获的信号,设置好回调函数,然后也是在回调函数中获取RunLoop,然后拿到所有的Mode,手动运行一遍。

    代码实现

    第一步,我创建了一个处理类 ZSExceptionHandler ,并添加一个单例方法。

    + (instancetype)shareInstance
    {
        static ZSExceptionHandler *handler = nil;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            handler = [[self alloc] init];
        });
        return handler;
    }

    第二步,在单例中对象实例化时,添加 异常捕获 和 signal 处理的 回调函数。

    - (void)startCatchExceptionHandler
    {
        // 1.捕获一些异常导致的崩溃
        NSSetUncaughtExceptionHandler(&HandleException);
        // 2.捕获非异常情况,通过signal传递出来的崩溃
        signal(SIGABRT, SignalHandler);
        signal(SIGILL, SignalHandler);
        signal(SIGSEGV, SignalHandler);
        signal(SIGFPE, SignalHandler);
        signal(SIGBUS, SignalHandler);
        signal(SIGPIPE, SignalHandler);
    }

    第三步,分别实现 异常捕获的回调 和 signal 的回调。里面可以都封装成异常模型 NSException

    void HandleException(NSException *exception)
    {
        ZSExceptionHandler *obj = ZSExceptionHandler.shareInstance;
        [obj handleException];
    }
    
    
    
    void SignalHandler(int signal)
    {
        ZSExceptionHandler *obj = ZSExceptionHandler.shareInstance;
    
        [obj handleException];
    }

    第四步,在崩溃前上传数据或者操作UI

    -(void) handleException
    {
    
        //如果有操作UI的地方 需要放到主线程
        @synchronized (self) {
            UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"程序崩溃了" message:@"如果你能让程序起死回生,那你的决定是?" preferredStyle:UIAlertControllerStyleAlert];
            UIAlertAction *sureAction = [UIAlertAction actionWithTitle:@"崩就蹦吧" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                
            }];
            UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"起死回生" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
                
            }];
            [alertController addAction:sureAction];
            [alertController addAction:cancelAction];
            
            [[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alertController animated:YES completion:nil];
        }
        
    
        //每种mode需要延迟3s去上传数据到后台
        BOOL need = YES;
        CFRunLoopRef runLoop = CFRunLoopGetCurrent();
        CFArrayRef allModes = CFRunLoopCopyAllModes(runLoop);
        if (need) {
            for (NSString *mode in (__bridge NSArray *)allModes) {
                CFRunLoopRunInMode((CFStringRef)mode, 3, false);
            }
        }
        CFRelease(allModes);
        
        NSSetUncaughtExceptionHandler(NULL);
        signal(SIGABRT, SIG_DFL);
        signal(SIGILL, SIG_DFL);
        signal(SIGSEGV, SIG_DFL);
        signal(SIGFPE, SIG_DFL);
        signal(SIGBUS, SIG_DFL);
        signal(SIGPIPE, SIG_DFL);
    
    }

    第五步,写一段会导致崩溃的代码

    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        NSArray *array =[NSArray array];
        NSLog(@"%@",[array objectAtIndex:1]);
    }

    第六步,App启动时,开启崩溃捕获

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        // Override point for customization after application launch.
        [ZSExceptionHandler.shareInstance startCatchExceptionHandler];
        return YES;
    }
    在北京的灯中,有一盏是我家的。这个梦何时可以实现?哪怕微微亮。北京就像魔鬼训练营,有能力的留,没能力的走……
  • 相关阅读:
    SpringBoot上传图片
    Java工具类(4) ------>运用easyexcel生成Excel表格
    SpringBoot(8) ------>集成SpringSecurity与Jwt
    docker_进阶
    jenkins基础
    C# 8 using declarations
    Sysmetric encryption and decryption via AES
    C# class implementation order of constructors include static constructor,constructor without modifiers and parameters, constructor with modifiers and parameters
    C# dictionary keys case insensitive
    Centos7安装Docker及运行hello-world
  • 原文地址:https://www.cnblogs.com/huangzs/p/15206810.html
Copyright © 2011-2022 走看看