状态恢复仅在连接到 Xcode 时有效

State restoration only works when connected to Xcode

我有一个运行计时器的应用程序,即使应用程序退出或 phone 关闭,计时器也应该保持 运行。 所以我尝试使用 shouldSaveApplicationStateshouldRestoreApplicationState 来做到这一点。我将这两种方法和 willFinishLaunchingWithOptions 添加到我的 appDelegate 中,并为涉及的每个视图控制器、导航控制器和标签栏控制器设置了恢复 ID。 然后在我想恢复的视图控制器上我这样做了:

override func encodeRestorableStateWithCoder(coder: NSCoder) {
    coder.encodeObject(startDate, forKey: "startDate")
    coder.encodeObject(startTime, forKey: "startTime")
    coder.encodeObject(elapsedTime, forKey: "elapsedTime")
    coder.encodeObject(playing, forKey: "playing")
    coder.encodeObject(timerLabel.text, forKey: "timerLabelText")
    super.encodeRestorableStateWithCoder(coder)
}

override func decodeRestorableStateWithCoder(coder: NSCoder) {
    startDate = coder.decodeObjectForKey("startDate") as! NSDate
    startTime = coder.decodeObjectForKey("startTime") as! NSTimeInterval
    elapsedTime = coder.decodeObjectForKey("elapsedTime") as! NSTimeInterval
    playing = coder.decodeObjectForKey("playing") as! Bool
    timerLabel.text = (coder.decodeObjectForKey("timerLabelText") as! String)
    super.decodeRestorableStateWithCoder(coder)
}

override func applicationFinishedRestoringState() {
    if playing {
        elapsedTime += startDate.timeIntervalSinceNow
        play()
    }
}

现在是奇怪的部分。当我的 phone 连接到 Xcode 并且我使用 Xcode 的播放和停止按钮启动和退出应用程序时,一切正常。但是,当我在 phone 与 Xcode 断开连接的情况下尝试同样的事情时,就像我什至根本没有设置状态恢复一样,应用程序完全忽略它,只显示第一个视图控制器.而且我什至无法调试,因为当我将 phone 连接到 Xcode 时,它就成功了。同样的事情发生在模拟器上。如果我使用 Xcode 的按钮,恢复工作。如果我只是从模拟器本身打开和关闭应用程序,它不会。

有什么想法吗?

当用户从多任务菜单中主动 "kills" 您的应用时,状态恢复不起作用。它仅在系统在后台静默终止您的应用程序以回收资源(例如,内存)时有效。

基本原理(以下是我自己的 speculation/interpretation)是这样的,状态恢复的全部目的是让用户回到应用程序他们上次离开了它,就好像它从未被终止过一样(从用户的角度来看)。

但如果用户明确终止应用程序,则意味着他们不希望它是"still running, as they left it"。

来源: This part of Apple's docs 指出:

  • The system automatically deletes an app’s preserved state when the user force quits the app. Deleting the preserved state information when the app is killed is a safety precaution. (As a safety precaution, the system also deletes preserved state if the app crashes twice during launch.) If you want to test your app’s ability to restore its state, you should not use the multitasking bar to kill the app during debugging. Instead, use Xcode to kill the app or kill the app programmatically by installing a temporary command or gesture to call exit on demand.

从 Xcode ("stop button") 中终止应用会复制 "non-user initiated termination",因此它尊重状态 preservation/restoration 流。