在后台每 X 分钟执行一次函数不起作用

111*_*110 3 iphone objective-c nsthread ios ios7

我使用此代码每 X 分钟执行一次函数:

- (void)executeEveryOneMinute
{
    [self myFunction];

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(60 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

        [self executeEveryOneMinute];

    });
}
Run Code Online (Sandbox Code Playgroud)

它在应用程序处于前台时工作。
但是当应用程序进入后台时,它不再起作用。
当我再次将应用程序返回到前台时,它会执行一次功能。
并继续每分钟再次调用函数。

那么如何让它在后台工作呢?

Rob*_*Rob 5

有关可能性的讨论,请参阅iOS 应用程序编程指南:应用程序状态和多任务处理后台执行和多任务处理部分。例如,您可以让应用程序在后台运行几分钟以完成一些有限长度的任务。或者,如果应用程序正在执行非常特殊的功能列表之一(引自上述文档),您可以继续在后台运行该应用程序更长的时间:

  • 在后台向用户播放可听内容的应用程序,例如音乐播放器应用程序
  • 在后台录制音频内容的应用程序。
  • 让用户随时了解其位置的应用程序,例如导航应用程序
  • 支持互联网协议语音 (VoIP) 的应用
  • 需要定期下载和处理新内容的应用
  • 从外部配件接收定期更新的应用程序

实现这些服务的应用程序必须声明它们支持的服务并使用系统框架来实现这些服务的相关方面。声明服务让系统知道您使用了哪些服务,但在某些情况下,实际上是系统框架阻止了您的应用程序被挂起。

但是,iOS 电池/电源管理的一个基本设计原则是随机应用程序不能(也不应该)继续在后台运行。但是,如果您分享您正在尝试做什么(即,您在该executeEveryOneMinute方法中具体做什么),如果可能,我们可以提供有关如何实现预期效果的建议。


如果您尝试在后台继续上传,在 iOS 7 及更高版本中,您应该考虑使用NSURLSession后台会话配置([NSURLSessionConfiguration backgroundSessionConfiguration:identifier];在 iOS 8 中有类似的方法)。这将继续尝试上传(自动,无需您进一步干预)不仅在您的应用程序离开前台之后,甚至在应用程序终止后(例如,由于内存压力或崩溃)。AFNetworking 提供了一个NSURLSession基于类的 ,AFURLSessionManager它支持这个(虽然它不是NSOperation基于的)。通过这种方式,您可以享受后台上传,但符合 Apple 的后台操作指南,与每 60 秒重试一次相比,对电池的影响较小。

我建议您参考 WWDC 2013 视频基础网络的新增功能的后半部分,它演示了这个过程(他们正在下载,但上传的想法是相同的)。