ios - 如果按下主页按钮,变量是否会保留在应用程序中?

标签 ios arrays

我有一个允许用户互相发送消息的应用程序。消息本地存储在用户手机的 SQL 库中。我有一个(所有对话的)数组(单个对话的)数组,电话实际使用它来填充标签值。此数组 [[pulledMessage]] 由应用程序的 didFinishLaunching 从 SQL 填充并且工作正常。我可以将任何新消息写入用户的 SQL 库,还可以更新该数组。我的问题是,我是否必须将 SQL 数据重新加载到应用程序 viewDidLoad 上的数组中(因为新消息将添加到对话中,但不会加载来自 SQL,因为加载是在 didFinishLaunching 中进行的)。这通常不会产生问题(因为在更新数组的同时填充 SQL 库基本上与从 SQL 加载到数组中是一样的),但是当用户“关闭”应用程序时会发生什么。我不是说硬关闭,比如终止它。我的意思是喜欢按下主页按钮并让它仍然在后台。 [[pulledMessage]] 是否持续存在以便我不需要重新运行它的填充(因此将加载放入 viewDidLoad),或者我是否需要这样做?

最佳答案

当应用程序暂停(通过点击主页按钮),并且用户重新启动它时,应用程序通常会再次进入前台状态,内存中的所有内容仍然存在。但是,在那种情况下,无论如何都不会调用 viewDidLoad,所以这并不重要。

您唯一会看到再次调用 didFinishLaunchingviewDidLoad 的情况是应用程序由于某种原因要终止。而且不仅仅是用户明确终止了您的应用程序。如果您的应用程序被挂起,用户启动另一个需要大量内存的应用程序以致您的应用程序被操作系统抛弃,也会发生这种情况。一旦你的应用被挂起,它可能会因为你无法控制的因素而被杀死,所以你应该优雅地处理它。但通常它不会被终止,而是会保留在内存中,这些方法不会被再次调用。

所以,最重要的是,如果您看到 didFinishLaunchingviewDidLoad 类方法被调用,这意味着该应用程序已完全重启,您将需要重新加载您的本例中的数据结构。


为了让您了解应用程序生命周期的运行情况,我向应用程序生命周期的关键事件添加了 os_log 语句。我使用了统一的日志记录系统(参见 WWDC 2016 Unified Logging and Activity Tracing 视频),因此我可以在不从 Xcode 运行应用程序时观察 macOS“控制台”应用程序的行为;从 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

The user presses the home button:

debug   14:46:46.996735 -0700   MyApp   com.domain.MyApp    AppDelegate applicationWillResignActive
debug   14:46:48.032994 -0700   MyApp   com.domain.MyApp    AppDelegate applicationDidEnterBackground

And the user restarts the app by tapping on the icon:

debug   14:47:09.263330 -0700   MyApp   com.domain.MyApp    AppDelegate applicationWillEnterForeground
debug   14:47:09.274849 -0700   MyApp   com.domain.MyApp    AppDelegate applicationDidBecomeActive

Note, it didn't call didFinishLaunching or viewDidLoad.


FYI, it's probably apparent from the above, but this is the app delegate code to generate those logging messages:

//  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)
    }

}

和 View Controller 代码:

//  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)
    }
}

我可能还会向您推荐 Execution States for AppsApp Termination iOS 应用编程指南:应用生命周期部分了解更多信息。

关于ios - 如果按下主页按钮,变量是否会保留在应用程序中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46384137/

相关文章:

c# - 在 C# 中使用 Property 获取数组元素

ios - 启动图像未显示在 iOS 应用程序中(使用 Images.xcassets)

ios - 如何在iOS中使用Google Place API以GMSPlaces而不是GMSAutocompletePrediction的形式获取自动完成的搜索位置结果?

ios - 使 UIScrollView 仅在内容部分起作用,而不是 "sides"

javascript - 我无法从数组中删除项目

javascript - 这是对总结对象数组有益的 JavaScript 重构吗?

ios - 从视频中提取缩略图时出现黑色空白图像

jquery - 点击 Safari Mobile 中的突出显示和 jQuery on() 函数会产生巨大的突出显示

c - 试图将对象传递给函数?

javascript - 解析数组Json来选择Tag