【问题标题】:How can I prevent my timer app from being terminated by iOS如何防止我的计时器应用程序被 iOS 终止
【发布时间】:2013-09-10 22:26:30
【问题描述】:

我有一个计时器应用程序,它会无限期地计数(直到用户停止计时器)。它的工作原理很像默认的 iOS 时钟秒表。

我已阅读有关成为负责任的后台应用程序的文章。我没有发生任何 UI 更改并在应用程序进入后台时停止计时器并在返回前台时恢复计时器。该应用确实每 30 分钟左右发送一次本地通知,以提醒用户休息一下。

问题:毫无疑问,我的应用会在几个小时(大约 2 到 6 小时之间)后终止,并且当前的计时器和信息会丢失。

我尝试过的事情:

-如前所述,我更改了我的应用程序以遵循成为负责任的后台应用程序的准则(在我让计时器 UI 计数并且计时器运行之前,即使在后台也是如此)。我认为这可以解决问题,因为我的应用没有占用太多内存或执行任何密集任务。

-我也尝试在 ApplicationWillTerminate 中保存当前计时器的数据(到 NSUserDefaults),然后在 DidFinishLaunchingWithOptions 上恢复它。它似乎不起作用。这几乎就像我的应用程序被强制退出或其他东西,因为如果 ApplicationWillTerminate 被调用,那么它将保存数据并在应用程序再次启动时恢复它。谜。

-目前我正在 ApplicationDidEnterBackground 上保存 NSTimer 的开始时间的 NSDate,使计时器无效,并在 ApplicationWillEnterForeground 上启动计时器并恢复开始时间。还是没有运气。

问题是这会影响到我的一小部分用户——所以这并不是每个人都会遇到的问题,这使得它更加混乱。当然,我仍然想修复它,因为它是一个非常蹩脚的错误——而且我自己也遇到过(在 iPhone 5 上),所以它不一定是旧 iPhone 内存不足或其他问题。

这真的让我大吃一惊,我已经完成了我的研究,并且还很好地搜索了堆栈溢出问题,但似乎没有找到任何可以帮助我的东西。

任何帮助将不胜感激,请随时提出更多问题或告诉我澄清。

【问题讨论】:

  • 操作系统杀死你的应用程序有什么关系?您可以在应用程序运行时安排本地通知,用户仍会看到这些通知。您可以保存开始时间,就像您目前正在做的那样。如果用户没有使用您的应用,则无需在后台使用空间和电源。
  • 因为当用户进入应用程序时,我希望他们看到自启动以来经过的时间以及应用程序被终止时的信息丢失。我认为问题是(正如 Wain 指出的)ApplicationWillTerminate 没有被调用——所以信息没有保存。我正在对此进行测试以确保。我仍然觉得奇怪的是,仅仅几个小时后我的应用程序就被杀死了,特别是因为我在后台没有发生任何事情。

标签: iphone ios objective-c nstimer multitasking


【解决方案1】:

applicationWillTerminate 基本上不会被调用。当您的应用程序在后台并从内存中删除时,它不会被调用。如果您的应用有一段时间没有被使用,您应该期望它会从内存中删除。 “一会儿”的时间长短取决于设备当时正在做什么......最好使用applicationDidEnterBackground:applicationWillResignActive:

【讨论】:

  • 很高兴知道 applicationWillTerminate 没有被调用。问题是我将数据保存在 applicationDidEnterBackground (计时器开始时间的 NSDate)中,然后在 ApplicationWillEnterForeground 上恢复。仍然没有运气。应用程序仍然会被杀死,就好像它是一个内存密集型应用程序一样。
  • 你必须期待它被“杀死”(从内存中删除)。如果您正确保存和恢复,它在恢复时不会对操作产生影响。
  • 所以当您说“正确保存和恢复”时,您的意思是保存到 NSUserDefaults(就像我尝试过的那样)并在 ApplicationDidFinishLaunchingWithOptions 上恢复值吗?还是说国家保护?
  • 为了澄清,你说的是保存 ApplicationDidEnterBackground 上的信息(而不是 WillTerminate,因为当我的应用程序从内存中拉出时它不会被调用),这样我就可以走了即使应用程序已从内存中删除。对吗?
  • 是的,使用applicationWillResignActive(不是applicationWillTerminate)。在applicationDidBecomeActive: 中恢复。 NSUserDefaults 很好。
【解决方案2】:

当您的应用程序进入后台时,记录您的计时器经过的时间(例如:在 NSUserDefaults 中或您喜欢的任何方式中)。同时记录当前时间。当应用程序回到前台时,查看您记录的两个值并相应地更新经过的时间,即:

elapsedTime = savedElapsedTime + (currentTime - timeWentIntoBackground)

您的应用确实没有理由需要在后台保持活动状态,这会消耗用户的电池来跟踪时间的流逝。

另外,不要依赖 applicationWillTerminate。使用 applicationWillEnterBackground。

【讨论】:

  • 所以我实际上就是这样做的,几个小时后我的应用程序仍然被杀死。我没有在后台执行任何任务(除了正在发送的那些 UILocalNotifications)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-01
相关资源
最近更新 更多