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

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

利用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
订单出现超时未关闭场景解决方案
订单出现超时未关闭场景解决方案
208 5
|
4月前
|
消息中间件 监控 Java
微软一面:订单超时未支付,如何自动关闭?
本文探讨了微软面试中关于订单超时自动关闭的设计题,提供了四种解决方案:定时器轮询、被动关闭、MQ延时消息及分布式超时中心。每种方案均详细阐述了实现思路、优缺点及适用场景。强调架构应基于业务需求,而非盲目追求高大上。适合不同规模的企业参考选用。
96 4
支付系统34----支付成功异步通知,处理重复通知,我们在我们程序当中找到处理订单的processOrder方法,我们要在更新订单状态和记录日志之前,先处理重复通知
支付系统34----支付成功异步通知,处理重复通知,我们在我们程序当中找到处理订单的processOrder方法,我们要在更新订单状态和记录日志之前,先处理重复通知
|
9月前
事务提交后回调
事务提交后回调
54 2
|
消息中间件 NoSQL 数据库
订单超时未支付自动取消--实现简述
订单超时未支付自动取消--实现简述
266 0
|
程序员 测试技术 数据库
实战! 项目单据确认状态未更新排查
实战! 项目单据确认状态未更新排查
|
消息中间件 存储 缓存
面试官:生成订单 30 分钟未支付,则自动取消,该怎么实现?
对上述的任务,我们给一个专业的名字来形容,那就是延时任务。那么这里就会产生一个问题,这个延时任务和定时任务的区别究竟在哪里呢?一共有如下几点区别
面试官:生成订单 30 分钟未支付,则自动取消,该怎么实现?
|
Java Spring
Spring - TransactionalEventListener 解决事务未提交读取不到数据问题(四)
Spring - TransactionalEventListener 解决事务未提交读取不到数据问题(四)
534 0
|
缓存 Java Spring
Spring - TransactionalEventListener 解决事务未提交读取不到数据问题(三)
Spring - TransactionalEventListener 解决事务未提交读取不到数据问题(三)
1132 0
|
Java 关系型数据库 MySQL
Spring - TransactionalEventListener 解决事务未提交读取不到数据问题(一)
Spring - TransactionalEventListener 解决事务未提交读取不到数据问题(一)
856 0