倒计时封装 程序进入后台不会暂停计时器


.h
/**
  时间改变时执行

 @param timeArray , , , 数组
 */
typedef void (^TimeChangeBlock)( NSMutableArray *timeArray);

.m
/**
  倒计时

 @param endTimeStep 倒计时一共有多少时间 ( )
 @param timeChange 每次时间改变时执行
 @param timeEnd 时间归 0 是执行
 */
- ( void )countDownTime:( NSInteger )endTimeStep withTimeChange:( TimeChangeBlock )timeChange withTimeEnd:( TimeChangeBlock )timeEnd{
    __block NSInteger timeout = endTimeStep/ 1000 ; // 倒计时时间
   
    // 队列(队列时用来确定该定时器存在哪个队列中)
    dispatch_queue_t queue = dispatch_get_main_queue ();
    // 创建 GCD 定时器
    dispatch_source_t timer = dispatch_source_create ( DISPATCH_SOURCE_TYPE_TIMER , 0 , 0 , queue);
   
    //    _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    dispatch_time_t start = dispatch_time ( DISPATCH_TIME_NOW , 0 * NSEC_PER_SEC ); // 开始时间
    uint64_t interval = 1 * NSEC_PER_SEC ; // 时间间隔
   
    // 设置 GCD 定时器开始时间,间隔时间
    dispatch_source_set_timer (timer, start, interval, 0 );
   
    // GCD 定时器处理回调方法
    dispatch_source_set_event_handler (timer, ^{

        NSInteger days = timeout/( 3600 * 24 );
        NSInteger hours = (timeout-days* 24 * 3600 )/ 3600 ;
        NSInteger minute = (timeout-days* 24 * 3600 -hours* 3600 )/ 60 ;
        NSInteger second = timeout-days* 24 * 3600 -hours* 3600 -minute* 60 ;
       
        NSMutableArray *timeArray = [ NSMutableArray arrayWithCapacity : 0 ];
        [timeArray addObject :[ NSNumber numberWithInteger :days]];
        [timeArray addObject :[ NSNumber numberWithInteger :hours]];
        [timeArray addObject :[ NSNumber numberWithInteger :minute]];
        [timeArray addObject :[ NSNumber numberWithInteger :second]];

        if (timeChange) {
            timeChange(timeArray);
        }

        timeout--;
        if (timeout< 0 ) { // 时间归 0
            // 关闭定时器
            dispatch_cancel (timer);
            if (timeEnd) {
                timeEnd(timeArray);
            }
        }
    });
   
    // GCD 定时器启动,默认是关闭的
    dispatch_resume (timer);
}



appdelegate.m
#pragma mark - 程序进入后台后 继续倒计时功能
// 程序进入后台不会影响到计时功能
- ( void )beginBackGroundTask:( UIApplication *)application {
    self . bgIdentifier =[application beginBackgroundTaskWithExpirationHandler :^( void ) {
       
        // 当应用程序留给后台的时间快要到结束时(应用程序留给后台执行的时间是有限的), 这个 Block 块将被执行
        // 我们需要在次 Block 块中执行一些清理工作。
        // 如果清理工作失败了,那么将导致程序挂掉
        // 清理工作需要在主线程中用同步的方式来进行
        dispatch_queue_t mainQueue = dispatch_get_main_queue ();
        AppDelegate *weakSelf = self ;
        dispatch_async (mainQueue, ^( void ) {
           
            AppDelegate *strongSelf = weakSelf;
            if (strongSelf != nil ){
                [ self endBackGroundTask ];
            }
        });
    }];
}

- ( void )applicationDidEnterBackground:( UIApplication *)application {
    [ super applicationDidEnterBackground :application];
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
   
    [ self beginBackGroundTask :application];
}

- ( void )applicationWillEnterForeground:( UIApplication *)application {
    [ super applicationWillEnterForeground :application];
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
    //application.applicationIconBadgeNumber = 0;
   
    [ self endBackGroundTask ];
   
}
// 结束程序进入后台的任务
- ( void )endBackGroundTask {
    // 每个对 beginBackgroundTaskWithExpirationHandler: 方法的调用 , 必须要相应的调用 endBackgroundTask: 方法。这样,来告诉应用程序你已经执行完成了。
    // 也就是说 , 我们向 iOS 要更多时间来完成一个任务 , 那么我们必须告诉 iOS 你什么时候能完成那个任务。
    // 也就是要告诉应用程序: 好借好还 嘛。
    // 标记指定的后台任务完成
    [[ UIApplication sharedApplication ] endBackgroundTask : self . bgIdentifier ];
    // 销毁后台任务标识符
    self . bgIdentifier = UIBackgroundTaskInvalid ;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值