如何让你的应用在后台可以继续处理未完事务

简介: 如何让你的应用在后台可以继续处理未完事务

利用GCD线程技术,加入MainDispatchQueue队列,它会将任务插入主线程的RunLoop当中去执行,所以显然是个串行队列,我们可以使用它来更新UI。关键是app切换到后台它还在正常运行。不过它运行的时间不是无限的,是在后台存活3分钟(这个是app独立运行的情况下是后台存活三分钟,在Xcode运行应用连接真机调试这个线程一直活着。)。当然你重新切换到前台时这个线程就又活了。由于它已经在主线程了,不能使用dispatch_sync(dispatch_get_main_queue(), ^{回主线程刷线UI否则崩溃。就是这种起线程的方式只能刷新一次UI。


下面是一个测试GCD线程使用MainDispatchQueue证明它在后台能正常运行的代码,做一个单例或页面,在代码中调用test函数,可以看到,它在后台还照常打日志。这个加入主线程的函数调用时,由于它一直独占cpu并且由于程序再sleep所以无法刷新UI,所以点击按钮无效。看来它的使用是很有局限性的:

//测试加入GCD的MainDispatchQueue队列里的线程在后台仍旧可以运行三分钟
-(void)test
{
    FLDDLogDebug(@"测试加入GCD的MainDispatchQueue队列线程在后台仍旧可以运行");
    dispatch_async(dispatch_get_main_queue(), ^{
        for(NSInteger i = 0; ; i++)
        {
            sleep(1);
            FLDDLogDebug(@"test:%ld", (long)i);
        }
    });
}

它能解决应用切换到后台,NSTimer无法实时计时的问题。再也不用通过几个变量记录时间,切换到前台再刷新时间显示了。

下面是记录app在后台存活时间的部分日志:

2018/12/19 10:45:53:537  ViewController.m:-[ViewController test]_block_invoke:31 Debug:test:12
2018/12/19 10:45:54:538  ViewController.m:-[ViewController test]_block_invoke:31 Debug:test:13

2018/12/19 10:48:55:352  ViewController.m:-[ViewController test]_block_invoke:31 Debug:test:193
2018/12/19 10:48:56:358  ViewController.m:-[ViewController test]_block_invoke:31 Debug:test:194
2018/12/19 10:48:57:363  ViewController.m:-[ViewController test]_block_invoke:31 Debug:test:195
2018/12/19 10:48:58:369  ViewController.m:-[ViewController test]_block_invoke:31 Debug:test:196
2018/12/19 10:48:59:374  ViewController.m:-[ViewController test]_block_invoke:31 Debug:test:197
2018/12/19 10:49:00:380  ViewController.m:-[ViewController test]_block_invoke:31 Debug:test:198
2018/12/19 10:49:01:384  ViewController.m:-[ViewController test]_block_invoke:31 Debug:test:199
2018/12/19 10:49:02:390  ViewController.m:-[ViewController test]_block_invoke:31 Debug:test:200

当你用全局队列dispatch_get_global_queue时,这个线程只要切换到后台立即停止了。当然你重新切换到前台时这个线程就又活了。

-(void)test
{
    FLDDLogDebug(@"测试加入GCD的MainDispatchQueue队列线程在后台仍旧可以运行");
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        for(NSInteger i = 0; ; i++)
        {
            sleep(1);
            FLDDLogDebug(@"test:%ld", (long)i);
        }
    });
}

这两种线程的使用具体代码见BITCocoaLumberjack的使用demo

目录
相关文章
|
4天前
|
NoSQL Java 数据库
重复点击提交、产生多笔数据、保持数据只操作一次---->接口幂等性校验
重复点击提交、产生多笔数据、保持数据只操作一次---->接口幂等性校验
4 0
|
10月前
|
消息中间件 NoSQL 数据库
订单超时未支付自动取消--实现简述
订单超时未支付自动取消--实现简述
175 0
|
前端开发 关系型数据库 MySQL
用户重复注册分析-多线程事务中加锁引发的bug
用户重复注册分析-多线程事务中加锁引发的bug
125 0
|
程序员 测试技术 数据库
实战! 项目单据确认状态未更新排查
实战! 项目单据确认状态未更新排查
|
缓存 Java Spring
Spring - TransactionalEventListener 解决事务未提交读取不到数据问题(三)
Spring - TransactionalEventListener 解决事务未提交读取不到数据问题(三)
964 0
|
消息中间件 存储 缓存
面试官:生成订单 30 分钟未支付,则自动取消,该怎么实现?
对上述的任务,我们给一个专业的名字来形容,那就是延时任务。那么这里就会产生一个问题,这个延时任务和定时任务的区别究竟在哪里呢?一共有如下几点区别
面试官:生成订单 30 分钟未支付,则自动取消,该怎么实现?
Kam
|
Java 测试技术 数据库
线上事务失效及失效场景总结记录
事务注解 @Transactional 失效的3种场景及解决办法
Kam
123 0
|
存储 算法 安全
同步工具(未完待更新)
在JDK1.7中,同步工具主要包括CountDownLatch(一次性栅栏)、Semaphore(信号量)、CyclicBarrier(循环同步栅栏)、Exchanger(线程间交换器)和Phaser。下面的篇幅中,将依次讲述每种同步工具的概念、用法和原理。
81 0
|
架构师 关系型数据库 MySQL
事务已提交,数据却丢了,赶紧检查下这个配置!!! | 数据库系列
有个星球水友提问: 沈老师,我们有一次MySQL崩溃,重启后发现有些已经提交的事务对数据的修改丢失了,不是说事务能保证ACID特性么,想问下什么情况下可能导致“事务已经提交,数据却丢失”呢?
631 0
事务已提交,数据却丢了,赶紧检查下这个配置!!! | 数据库系列