如何让NSTimer变相的在后台长时间运行

我们都知道NStimer 在iPhone里面后台的可以运行时间是3分钟。即使挂在前台,只要手机开始锁屏了。NSTimer会立即停止运行。即使如下面这样
- (void)applicationDidEnterBackground:(UIApplication *)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.
    UIApplication*   app = [UIApplication sharedApplication];
    __block    UIBackgroundTaskIdentifier bgTask;
    bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
        dispatch_async(dispatch_get_main_queue(), ^{
            if (bgTask != UIBackgroundTaskInvalid)
            {
                bgTask = UIBackgroundTaskInvalid;
            }
        });
    }];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        dispatch_async(dispatch_get_main_queue(), ^{
            if (bgTask != UIBackgroundTaskInvalid)
            {
                bgTask = UIBackgroundTaskInvalid;
            }
        });
    });
    
}

搭配

NSError *setCategoryErr = nil;
    NSError *activationErr  = nil;
    [[AVAudioSession sharedInstance]
     setCategory: AVAudioSessionCategoryPlayback
     error: &setCategoryErr];
    [[AVAudioSession sharedInstance]
     setActive: YES
     error: &activationErr];

也不能完全实现效果 进入后台超过一定时间还是会被停止。而且还有审核的风险

在我的APP里面我使用到了定位。一直开启了定位但是过了一定的时间定时器还是会被停止。虽然一直在定位

经过调试我发现程序锁屏和解锁的时候仍然分别会发送

UIApplicationDidEnterBackgroundNotification和 UIApplicationWillEnterForegroundNotification这2个通知。因为程序进入后台啊UI上的操作一直都是停止的。所以我们可以在程序再次激活的时候去刷新界面。这样我们只要保留下进入后台的时间保留下当前的时间,程序进入前台的时候计算他们的时间差值再加上之前定时器已经运行的时间。计算时间差值的方法如下

            NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
            unsigned int unitFlags = NSSecondCalendarUnit;//年、月、日、时、分、秒、周等等都可以
            NSDateComponents *comps = [gregorian components:unitFlags fromDate:self.EnterBackGroundTime toDate:[NSDate date] options:0];
            
            NSLog(@"comps%d",[comps second]);

这样我们就可以得到所有的时间。数据类的获取一般都不交给定时器。通过定位循环获取。这样计算平均速度什么的就不会有什么误差。

还有我们可以新建一个方法通过sleep实现定时器的效果,这样的实现在屏幕锁定或者进入后台的时候仍然有效。不过一定要放到子线程中否则会堵塞界面操作。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值