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;
    }
    在北京的灯中,有一盏是我家的。这个梦何时可以实现?哪怕微微亮。北京就像魔鬼训练营,有能力的留,没能力的走……
  • 相关阅读:
    牛客网 二叉树的镜像 JAVA
    牛客网 反转链表 JAVA
    牛客网 调整数组顺序使奇数位于偶数前面 JAVA
    Integer to Roman LeetCode Java
    Valid Number leetcode java
    Longest Common Prefix
    Wildcard Matching leetcode java
    Regular Expression Matching
    Longest Palindromic Substring
    Add Binary LeetCode Java
  • 原文地址:https://www.cnblogs.com/huangzs/p/15206810.html
Copyright © 2011-2022 走看看