我有一个应用程序,允许用户相互发送消息。消息本地存储在用户手机的SQL库中。我有一个数组(所有对话)的数组(个别对话),手机实际用来填充标签值。这个数组数组[[pulledMessage]]
由应用程序didFinishLaunching
从SQL填充,并且工作正常。我可以将任何新消息写入用户的SQL库,也可以更新该数组。我的问题是,我是否必须将SQL数据重新加载到应用程序viewDidLoad
上的数组中(因为新消息将添加到会话中但不会被加载< em> from SQL,因为加载在didFinishLaunching
中。这通常不会产生问题(因为在更新数组的同时填充SQL库与从SQL加载到数组中基本相同),但是当用户&#34;关闭时#会发生什么? 34;该应用程序。我并不是说硬关闭,就像终止它一样。我的意思是按下主页按钮并将其保留在后台。 [[pulledMessage]]
是否仍然存在,以便我不需要重新运行其填充(因此将加载放入viewDidLoad
),或者我是否需要这样做?
答案 0 :(得分:1)
当应用程序暂停时(通过点击主页按钮),并且用户重新启动它,应用程序通常只会再次进入前台状态并且内存中的所有内容仍然存在。但是,在这种情况下,无论如何都不会调用viewDidLoad
,所以它并不重要。
您再次调用didFinishLaunching
和viewDidLoad
的唯一时间是应用程序因某种原因被终止。并且不仅仅是用户明确终止了您的应用。如果您的应用程序被暂停,用户也会启动另一个需要大量内存的应用程序,以便您的应用程序被操作系统放弃,这种情况也会发生。一旦您的应用程序被暂停,它可能会因您无法控制的因素而被杀死,因此您应该优雅地处理此问题。但通常它不会被终止,而是留在记忆中,这些方法不会再被调用。
因此,如果您看到调用了didFinishLaunching
和viewDidLoad
种方法,那么这意味着应用程序已完全重新启动,并且您希望在这种情况下重新加载数据结构。
为了让您可以看到应用生命周期的实际应用,我将os_log
语句添加到应用生命周期的关键事件中。我使用了统一日志记录系统(参见WWDC 2016 Unified Logging and Activity Tracing视频),因此我可以在不从Xcode运行应用程序时观察macOS“Console”应用程序的行为。从Xcode运行它可以改变应用程序生命周期行为。然后,当我从设备(而不是Xcode)启动应用程序时,我在macOS“控制台”应用程序中观看了这些内容。这就是我所看到的:
用户首次启动应用程序:
debug 14:46:25.256978 -0700 MyApp com.domain.MyApp AppDelegate didFinishLaunching debug 14:46:25.258476 -0700 MyApp com.domain.MyApp ViewController viewDidLoad debug 14:46:25.258550 -0700 MyApp com.domain.MyApp ViewController viewWillAppear debug 14:46:25.261261 -0700 MyApp com.domain.MyApp ViewController viewDidAppear debug 14:46:25.300246 -0700 MyApp com.domain.MyApp AppDelegate applicationDidBecomeActive
用户按下主页按钮:
debug 14:46:46.996735 -0700 MyApp com.domain.MyApp AppDelegate applicationWillResignActive debug 14:46:48.032994 -0700 MyApp com.domain.MyApp AppDelegate applicationDidEnterBackground
用户点击图标重新启动应用程序:
debug 14:47:09.263330 -0700 MyApp com.domain.MyApp AppDelegate applicationWillEnterForeground debug 14:47:09.274849 -0700 MyApp com.domain.MyApp AppDelegate applicationDidBecomeActive
注意,它没有调用didFinishLaunching
或viewDidLoad
。
仅供参考,从上面可能很明显,但这是用于生成这些日志消息的app委托代码:
// AppDelegate.swift
import UIKit
import os.log
private let log = OSLog(subsystem: "com.domain.MyApp", category: "AppDelegate")
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
os_log("didFinishLaunching", log: log, type: .debug)
return true
}
func applicationWillResignActive(_ application: UIApplication) {
os_log("applicationWillResignActive", log: log, type: .debug)
}
func applicationDidEnterBackground(_ application: UIApplication) {
os_log("applicationDidEnterBackground", log: log, type: .debug)
}
func applicationWillEnterForeground(_ application: UIApplication) {
os_log("applicationWillEnterForeground", log: log, type: .debug)
}
func applicationDidBecomeActive(_ application: UIApplication) {
os_log("applicationDidBecomeActive", log: log, type: .debug)
}
func applicationWillTerminate(_ application: UIApplication) {
os_log("applicationWillTerminate", log: log, type: .debug)
}
}
视图控制器代码:
// ViewController.swift
import UIKit
import os.log
private let log = OSLog(subsystem: "com.domain.MyApp", category: "ViewController")
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
os_log("viewDidLoad", log: log, type: .debug)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
os_log("viewWillAppear", log: log, type: .debug)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
os_log("viewDidAppear", log: log, type: .debug)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
os_log("viewWillDisappear", log: log, type: .debug)
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
os_log("viewDidDisappear", log: log, type: .debug)
}
}
我可能还会推荐您参阅适用于iOS的应用程序编程指南中的Execution States for Apps和App Termination部分:应用程序生命周期以获取更多信息。