iphone - NSTimers 在后台

Posted

技术标签:

【中文标题】iphone - NSTimers 在后台【英文标题】:iphone - NSTimers in background 【发布时间】:2012-02-15 02:59:59 【问题描述】:

我正在开发一个必须在后台运行的应用程序。这是一个基于位置的应用程序,所以它一直在运行,操作系统不会杀死它。

它应该每 10 秒发送一些信息(仅用于调试),我在后台设置了一个计时器。我在函数中设置了一个断点,该断点应该每 10 秒执行一次,它永远不会被调用,但是如果我暂停应用程序然后继续调用计时器,然后计时器每 10 秒执行一次而没有问题,很奇怪吧?

当我不调试时,我以为计时器会一直执行,但事实并非如此,就像我没有暂停调试一样。

我的问题是为什么?计时器设置正确(我假设),因为它在暂停后工作,但它不是。

有什么想法吗?

我设置定时器的方式是:

self.timer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(doStuff) userInfo:nil repeats:YES];

在函数中我连接到一个网络服务。

谢谢。

【问题讨论】:

这是关于定时器,不是调试;修正你的标题,请。并且“objective-c”是你在标记这个问题方面能做的最好的事情吗? NSTimers running in background? 的可能重复项 【参考方案1】:

我有一个类似的应用程序设计,并被困在同一件事上。我在互联网上的某个地方找到的是添加这种类型的声明applicationDidEnterBackground:

    UIBackgroundTaskIdentifier locationUpdater =[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^
         [[UIApplication sharedApplication] endBackgroundTask:locationUpdater];
        locationUpdater=UIBackgroundTaskInvalid;
      ]; 

这告诉操作系统你还有事情要做而不是阻止它。

我的计时器已附加到此功能

 //this is a wrapper method to fit the required selector signature
- (void)timeIntervalEnded:(NSTimer*)timer 
     [self writeToLog:[NSString stringWithFormat:@"Timer Ended On %@",[NSDate date]]];
     [self startReadingLocation];
     [timer invalidate];
     timer=nil;

我在我的位置管理器委托方法中设置了计时器。

我感觉到你的痛苦。我发现这些东西非常挑剔。这对我有用。我希望它有所帮助。我发现你在后台可以做的事情并没有任何真正的限制。

【讨论】:

实际上它并没有解决我的整个问题。现在我得到一个崩溃日志,显然是因为我没有结束后台任务,那是因为只要应用程序在后台,任务就永远不会完成。 NStimer 将无休止地重复。那可能吗?还是因为它是一个定位应用程序,所以我应该将操作与 GPS 挂钩? 我不确定崩溃的原因。我能够在后台维护套接字连接,因此我很确定您不仅限于基于位置的事物。但正如我所说,这些问题并不是最容易解决的。抱歉,我无法提供更多帮助。我的计时器将无休止地运行(据我所知)要检查的一件事是打印出 backgroundTimeRemaining (它永远不会下降并且非常大) 所以让我理解。您在 applicationDidEnterBackground 中执行“beginBackgroundTaskWithExpirationHandler”。而当你的 NSTimer 过期时,你不会再使用“beginBackgroundTaskWithExpirationHandler”,当它进入后台时你所做的就足够了,对吗? 没错,我在应用程序委托类之外有一个计时器,该计时器不断运行/到期/重置。并且在它进入后台之前就开始BackgroundTaskWithExpirationHandler。我的计时器方法与我发布的完全一样。确保您在 plist 的背景模式字段中有位置 这对我来说非常有效,只是它需要在 UIBackgroundTaskIdentifier 之前使用 __block。谢谢!【参考方案2】:

您可以在后台执行的操作可能会受到限制。在进入后台之前尝试将计时器添加到运行循环。即使这样也可能行不通;您唯一可以在后台运行的代码可能是您注册的核心位置方法调用的代码(例如locationManager:didUpdate...)。但我的印象是,在您开始进入后台之前已经运行的计时器将继续运行。

【讨论】:

但这并不能解释为什么我调试它可以工作。这就是我不明白的。我假设应用程序的行为与调试或运行方式相同 我相信,如果您尝试了我的建议(在前台设置计时器),它会解决问题。这实际上可能与您接受的解决方案相同。您的问题是您已经在后台运行并且在设置计时器之前您的 runloop 已经停止运行。在断点处暂停并在后台恢复时为您的 runloop 提供了新的运行机会,因此此时计时器已添加到 runloop。这是猜测,但我相信它可以解释这些现象。

以上是关于iphone - NSTimers 在后台的主要内容,如果未能解决你的问题,请参考以下文章

在后台播放音乐时减少电池消耗

在 iPhone 后台下载

在后台将数据从 iWatch 发送到 iPhone

iphone - 在后台播放音频流

如何声明必须在后台运行的 iPhone 应用程序?

iPhone:重复后台任务