美文网首页iOS常用
iOS 杀掉进程后,App仍在后台工作

iOS 杀掉进程后,App仍在后台工作

作者: MQ_Twist | 来源:发表于2020-07-23 11:59 被阅读0次

    值得做的事情,就是值得做对的事情。

    前言

    昨天小伙伴有个需求,就是用户在杀掉app后,要把一些用户习惯信息的保存到本地。实现起来很简单,就是在Appdelegate中的applicationWillTerminate的代理方法里面写相应的业务代码就行了。但是问题来了,保存本地失灵时不灵的,仔细一看原来他用dispatch_barrier_async实现了一个多读单写,在写的时候是异步,所以出现了上面的问题。
    代码简化后大致思想如下:

    dispatch_queue_t queue = dispatch_queue_create(0, DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
         //模拟耗时处理
         sleep(1);
         NSLog(@">>>>do something");
    });
    

    先抛开其它的不谈,就上面的问题的本质是 杀掉app时,仍执行异步任务。对此,目前我想到两种解决方式。

    Demo地址:传送门

    • 第一种,使用信号量dispatch_semaphore_t
    dispatch_queue_t queue = dispatch_queue_create(0, DISPATCH_QUEUE_CONCURRENT);
    dispatch_semaphore_t sem = dispatch_semaphore_create(0);
    dispatch_async(queue, ^{
        //模拟耗时处理
        sleep(1);
        NSLog(@">>>>do something");
        dispatch_semaphore_signal(sem);
    });
    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
    
    • 第二种,线程常驻
    - (void)residentThread {
        ///!!!:放在前面不行,要放在后面
    //    [self performSelector:@selector(run) onThread:[NSThread currentThread] withObject:nil waitUntilDone:YES];
        dispatch_queue_t queue = dispatch_queue_create(0, DISPATCH_QUEUE_CONCURRENT);
        dispatch_async(queue, ^{
            //模拟耗时处理
            sleep(2);
            [self.timer invalidate];
            self.timer = nil;
            NSLog(@">>>>do something");
        });
        [self performSelector:@selector(run) onThread:[NSThread currentThread] withObject:nil waitUntilDone:YES];
    }
    
    - (void)run {
        NSTimer *timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(go) userInfo:nil repeats:YES];
        [timer fire];
        self.timer = timer;
        [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
        [[NSRunLoop currentRunLoop] run];
        ///!!!:放在后面任务处理完后,还在继续
    //    self.timer = timer;
    }
    
    - (void)go {
        NSLog(@">>>timer");
    }
    

    总结

    不管是哪种,本质都是阻塞主线程,然后后台继续执行任务。

    • 优势

    可以实现杀掉APP,后台任务执行。

    • 潜在问题

    如果这个任务很耗时,那么就会一直阻塞,在任务没有完成之前再次打开app时,会卡住。这时需要做相应处理。

    后记

    线程常驻那部分有2点标记重要,有兴趣的小伙伴可以研究一下。

    相关文章

      网友评论

        本文标题:iOS 杀掉进程后,App仍在后台工作

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