程序切换到后台,计时器可继续定时解决方案

项目中的需求:应用进入到后台后,定时器继续进行定时任务

解决:

先上代码

  // 五分钟倒计时
    [self countDown];
    __block UIBackgroundTaskIdentifier bgTask;
    bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
        dispatch_async(dispatch_get_main_queue(), ^{
            if (bgTask != UIBackgroundTaskInvalid)
            {
                [[UIApplication sharedApplication] endBackgroundTask:bgTask];
                bgTask = UIBackgroundTaskInvalid;
            }
        });
    }];
    
-(void)countDown{
    
    //在这里执行事件
    if (_timer ==nil) {
        // 获取全局队列
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        // 创建定时器
        _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
        // 开始时间
        //    dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC));
        dispatch_time_t start =  dispatch_walltime(NULL, 0);
        // 重复间隔
        uint64_t interval = (uint64_t)(1.0 * NSEC_PER_SEC);
        // 设置定时器
        dispatch_source_set_timer(_timer, start, interval, 0);
        // 设置需要执行的事件
        dispatch_source_set_event_handler(_timer, ^{
       
            NSLog(@"%ld", (long)num);
            num++;
            if (num > 60*5){
                NSLog(@"end");
                num = 0;
                // 关闭定时器
                dispatch_source_cancel(_timer);
                //进入验证手机界面
                //[[NSUserDefaults standardUserDefaults] setObject:@"2" forKey:@"timeFlag"];
            }
        });
        // 开启定时器
        dispatch_resume(_timer);
    }else{
        // 关闭定时器
        dispatch_source_cancel(_timer);
    }
    
}

分析计时器只在程序active时工作,当用户按起HOME键时,计时器停止,因为当程序进入后台时,这个线程就被挂起不工作,当然计时器就会被“暂停”。


系统原理: iOS为了让设备尽量省电,减少不必要的开销,保持系统流畅,因而对后台机制采用“假后台”模式。一般开发者开发出来的应用程序后台受到以下限制:

1.用户按Home之后,App转入后台进行运行,此时拥有180s后台时间(iOS7)或者600s(iOS6)运行时间可以处理后台操作
2.当180S或者600S时间过去之后,可以告知系统未完成任务,需要申请继续完成,系统批准申请之后,可以继续运行,但总时间不会超过10分钟(系统提供beginBackgroundTaskWithExpirationHandler方法)。
3.当10分钟时间到之后,无论怎么向系统申请继续后台,系统会强制挂起App,挂起所有后台操作、线程,直到用户再次点击App之后才会继续运行。

当然iOS为了特殊应用也保留了一些可以实现“真后台”的方法,摘取比较常用的(实现后台长连接):
1.VOIP
2.定位服务(建议使用)
3.后台下载
4.在后台一直播放无声音乐(容易受到电话或者其他程序影响,所以一般不考虑)

beginBackgroundTaskWithExpirationHandler作用:

beginBackgroundTaskWithExpirationHandler是向系统发出申请延长后台不被挂起时间

endBackgroundTask是告诉系统已完事,可以结束了,


你可能感兴趣的:(iOS-进击之路)