应用程序生命周期和状态转换操作策略

iOS 应用程序生命周期


基本概念介绍

The Main Function - 程序的入口

main函数是每个基于C的应用程序的入口,iOS也是这样。在Xcode中开发iOS程序的话,Xcode会自动为你创建这个函数作为你工程的一部分。

1
2
3
4
5
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}

main函数控制UIKit framework的工作。UIApplicationMain函数通过创建应用程序的核心对象,从可用的storyboard文件加载应用程序的用户界面,调用自定义代码,以便让你可以在程序启动时进行一些初始设置,并将应用程序的运行循环启动。

The Structure of an App - 程序的结构

在启动过程中,UIApplicationMain函数设置了几个关键对象,启动应用程序并开始运行它。 每个iOS应用程序的核心都是UIApplication对象,其工作是为了方便系统与应用程序中的其他对象之间的交互。

一个iOS应用程序中包含的关键对象:

一个iOS应用程序中各个对象的所起到的作用:

Object Description
UIAppplication UIApplication对象管理着App的事件循环和一些高级App行为,并向它的委托对象报告App的状态转换和一些特殊事件。
Appdelegate Appdelegate是你编写的程序代码的核心 ,它与UIApplication对象一起工作,处理应用程序初始化,状态转换和许多高级App行为。 这个对象也是唯一一个保证在每个应用程序中都出现的对象,因此通常用于设置应用程序的初始数据结构。
ViewController View Controller对象管理着你的App内容在屏幕上是如何呈现的。一个View Controller对象管理着一个视图和这个视图的子视图。
UIWindow UIWindow对象协调屏幕上一个或多个视图的呈现。 大多数应用程序只有一个窗口,它在主屏幕上显示内容,但应用程序可能会在外部显示器上显示内容的附加窗口。要更改应用程序的内容,可以使用视图控制器更改相应窗口中显示的视图。 你永远不会更换窗口本身。除了托管视图之外,Windows还可以使用UIApplication对象将事件传递给的视图和控制器。
View,Control and Layer View和Control提供了应用内容的可视化表示。 除了包含View和Control之外,应用程序还可以将Core Animation图层纳入其视图和控制层次结构中。 层对象实际上才是表示可视内容的数据对象。

The Main Run Loop - 主运行循环

应用程序的主运行循环处理所有与用户相关的事件。 UIApplication对象在启动时设置主运行循环,并使用它来处理事件并处理基于视图的接口的更新。

顾名思义,主运行循环在应用程序的主线程上执行,这确保了与用户相关的事件按照接收的顺序连续处理。

当用户与设备进行交互时,与这些交互相关的事件由系统生成,并通过由UIKit设置的特殊端口传送到应用。 事件在应用程序内部进入队列,并逐个分派到主运行循环执行。UIApplication对象是接收事件的第一个对象,并且决定需要做什么来处理这个事件。 触摸事件通常被分派到主窗口对象,主窗口对象又将其发送到触摸发生的视图。

可以在iOS应用程式中分发许多类型的事件。 最常见的如下表所示。 这些事件大多是使用应用程序的主运行循环分发的,但也有些不是。 一些事件被分发到一个委托对象或被分发给你提供的一个block。

事件类型 分发对象 备注
触摸事件 事件发生的视图 视图是响应者对象。任何没有被当前视图处理的触摸事件都会被沿着响应链继续向下分发进行处理。
遥控器事件和摇动运动事件 首要响应对象 遥控器事件用于控制媒体播放,并由耳机和其他附件产生。
加速度计、磁力仪和陀螺仪 你指定的对象 与加速度计,磁力计和陀螺仪硬件相关的事件传递给你指定的对象。
定位 你指定的对象 你注册定位服务以接收使用Core Location框架位置的事件。
重绘 需要更新的视图 重绘事件不涉及事件对象,而是简单地调用视图来绘制自身。

一些事件,如触摸和遥控事件,由你的应用程序的响应者对象处理。响应者对象在你的应用程序中无处不在。 大多数事件都针对特定的响应者对象,但如果需要处理事件,则可以将其传递给其他响应方(通过响应者链)。 例如,不处理事件的视图可以将事件传递到其父视图或父视图控制器。

触摸控件(如按钮)中发生的事件的处理方式与在许多其他类型的视图中发生的触摸事件的处理方式不同。 通常只有有限数量的交互可能与控件相关联,因此这些交互被重新封装到动作消息中并传递到适当的目标对象。 这种目标动作(Target-Action)设计模式可以轻松地使用控件来触发你应用中自定义代码的执行。

Execution States for Apps - 应用程序的执行状态

在任何给定的时刻,你的应用程序都处在下表所列的状态之一。 系统会改变应用程序的状态以响应整个系统中发生的操作。

状态 描述
Not running 应用程序没有运行或被系统终止运行。
Inactive 应用程序正在前台运行,但当前没有收到事件 (它可能正在执行其他代码)。应用程序通常在转换到不同的状态时暂时保持在此状态。
Active 应用程序正在前台运行,并且正在接收事件(这是前台应用程序的正常模式)。
Background 应用程序在后台执行代码。 大多数应用程序短暂地进入此状态。 但是,请求额外执行时间的应用程序可能会保持此状态一段时间。
Suspended 应用程序是在后台,但不执行代码。 系统将应用程序自动转换到这个状态,在这样做之前并不会通知应用程序。 挂起时,应用程序保留在内存中,但不执行任何代码。当出现低内存条件时,系统可能会清除已挂起的应用程序,以为前台应用程序腾出更多空间。

下图展示了应用程序在各种状态之间的转换:

大多数状态转换伴随着对应用程序委托对象的方法的相应调用 ,这些方法是你以适当方式响应状态变更的地方。

  • application:willFinishLaunchingWithOptions:

    告诉代理对象启动过程已经开始,但还没有发生状态恢复。

  • application:didFinishLaunchingWithOptions:

    告诉代理对象启动过程快要完成,应用程序快要准备好运行。

  • applicationDidBecomeActive:

    告诉代理对象应用程序已经处于Active状态。

  • applicationWillResignActive:

    告诉代理对象应用程序即将进入Inactive状态。

  • applicationDidEnterBackground:

    告诉代理对象应用程序已经进入后台。

  • applicationWillEnterForeground:

    告诉代理对象应用程序即将进入前台。

  • applicationWillTerminate:

    告诉代理对象应用程序即将被终止。

App Termination - 应用程序的终止

应用程序必须随时准备终止运行,不应等待保存用户数据或执行其他关键任务。 System-initiated termination是应用程序生命周期的正常部分。该系统通常终止应用程序,以便它可以回收内存并为用户启动的其他应用程序腾出空间,但是系统也可能会终止行为不当或未及时响应事件的应用程序。

挂起的应用程序终止时不会收到通知,系统将杀死该进程并回收相应的内存。如果一个应用程序当前在后台运行并且没有挂起,系统会在终止之前调用应用程序委托的applicationWillTerminate:。当设备重新启动时,系统不会调用此方法。

除了系统终止你的应用程序,用户可以使用多任务UI显式地终止你的应用程序。System-initiated termination与终止挂起的应用程序具有相同的效果。该应用程序的进程被杀死,并且不会有通知发送到该应用程序。

Threads and Concurrency - 线程和并发

系统创建你的应用程序的主线程,你可以根据需要创建其他线程来执行其他任务。

对于iOS应用,首选技术是使用Grand Central Dispatch(GCD),操作对象和其它异步编程接口,而不是自己创建和管理线程。 GCD等技术可以让你定义想要执行的工作以及要执行的顺序,但让系统决定如何在可用的CPU上执行该工作。让系统处理线程管理简化了必须编写的代码,使得更容易确保代码的正确性,并提供更好的整体性能。

在考虑线程和并发时,请考虑以下几点:

  • 涉及视图,核心动画和许多其他UIKit类的工作通常必须发生在应用程序的主线程上。

  • 长时间的任务(或潜在的长度任务)应始终在后台线程上执行。任何涉及网络访问,文件访问或大量数据处理的任务都应使用GCD或操作对象异步执行。

  • 在启动时,尽可能将任务从主线程移出。在启动时,您的应用程序应尽可能快地设置用户界面。只有有助于设置用户界面的任务才能在主线程上执行。

    所有其他任务应该是异步执行的。


操作应用程序的状态转换


对于应用程序的任何一个可能的运行状态,系统都对你的应用程序有不同的期望。当应用程序的状态发生转换时,系统会通知应用对象,应用对象又通知其代理。你可以使用UIApplicationDelegate协议的状态转换方法来检测这些状态变化并进行适当的响应。

应用程序启动时应该做什么

当应用程序启动(进入前台货后台)时,你应该使用应用程序委托对象的application:willFinishLaunchingWithOptions:application:didFinishLaunchingWithOptions:方法执行一些操作:

  • 检查启动选项字典的内容(launch options dictionary),了解应用程序启动的原因,并作出适当的响应。

  • 初始化应用程序的关键数据结构。

  • 准备应用程序的窗口和视图以进行内容显示。

    • 使用OpenGL ES进行绘图的应用程序不能使用这些方法来准备绘图环境,使用OpenGL ES绘图应该在applicationDidBecomeActive:方法中进行准备。

    • Show your app window from your application:willFinishLaunchingWithOptions: method. UIKit delays making the window visible until after the application:didFinishLaunchingWithOptions: method returns.

    • application:willFinishLaunchingWithOptions:方法中配置如何显示应用程序的Window。UIKit延迟Window的显示直到application:didFinishLaunchingWithOptions:方法进行了返回。

在启动时,系统会自动的加载应用程序的主要storyBoard文件,并加载初始视图控制器。对于支持状态恢复的应用程序,状态恢复机制会在调用application:willFinishLaunchingWithOptions:application:didFinishLaunchingWithOptions:方法之间将应用程序恢复到以前的状态。使用application:willFinishLaunchingWithOptions:方法显示应用程序窗口,并确定状态恢复是否应该发生。使用application:didFinishLaunchingWithOptions:方法对应用程序的用户界面进行任何最终调整。

application:willFinishLaunchingWithOptions:application:didFinishLaunchingWithOptions:方法应始终尽可能轻量级,以减少应用程序的启动时间。如果应用程序没有及时完成其启动周期,系统将使其无法响应。因此,任何可能减慢启动速度的任务(如访问网络)都应该在辅助线程上执行。

The Launch Cycle - 启动周期

当你的应用程序启动后,在短暂的停留在非活动状态(Inactive)后,将会从非运行状态(Not Running)转换到活动状态(Active)或后台状态(Background)。作为启动周期的一部分,系统会为你的应用程序创建一个进程和一个主线程,并在主线程中调用应用程序的main函数。

下图显示了应用程序启动到前台时发生的事件序列,包括调用的应用程序委派方法。

当你的应用程序启动到后台时,通常要处理一些后台事件,启动周期会有些许改变。主要的不同在于,在后台的应用程序不是处于活动状态,只是进入后台来处理一些事件,之后可能会被挂起。当启动到后台时,系统仍然会加载用户界面文件,但不会显示应用程序的窗口。

你可以通过在代理方法 application:willFinishLaunchingWithOptions:application:didFinishLaunchingWithOptions:中检查UIApplicationapplicationState属性来决定应用程序是启动到前台还是后台。当你的应用程序启动到前台时,这个属性的值是UIApplicationStateInactive,当你的应用程序启动到后台时,这个属性的值是UIApplicationStateBackground

Launching in Landscape Mode - 以横屏模式启动

对于界面只使用横屏的应用程序来说,必须明确地请求系统以横屏模式启动。通常来说,应用程序以纵屏模式启动,只有在需要适应设备的方向的时候才旋转屏幕的方向。 对于支持纵向和横向方向的应用程序,应始终为纵向模式配置视图,然后让视图控制器处理任何旋转。
但是,如果您的应用程序支持横向而不是纵向方向,请执行以下任务,让使其以横向模式启动:

  • 像你应用程序中的Infl.plist文件中添加UIInterfaceOrientation字段,并将其值设为UIInterfaceOrientationLandscapeLeftUIInterfaceOrientationLandscapeRight
  • 在横屏模式下布局你的视图并确保视图的布局和自动调整大小选项设置正确。
  • 重写试图控制器的shouldAutorotateToInterfaceOrientation:方法并在左向横屏或右向横屏时返回YES,在纵屏模式下返回NO

重要提示: 应用程序应该总是用视图控制器来管理基于窗口(Window)的内容。

Info.plist文件中的UIInterfaceOrientation字段告诉iOS系统该如何配置应用程序状态栏的方向(如果显示的话)以及任何视图控制器管理的视图在启动时的方向。视图控制器根据这个字段设置它的视图的初始方向。 使用此字段相当于在执行你的applicationDidFinishLaunching:方法的早期调用应用程序的setStatusBarOrientation:animated:方法。

Installing App-Specific Data Files at First Launch - 配置应用程序数据文件

你可以使用应用程序的第一个启动周期来设置任何应用程序运行所需要的数据或配置文件。 应用程序特定的数据文件应在应用程序沙箱的Library/Application Support/<bundleID>/目录中创建,其中是应用程序的标识符。你可以根据需要细分目录来组织你的数据文件。

如果应用程序包中包含你打算进行修改的数据文件,你应该将要修改的数据文件从应用程序的数据包中复制出来进行修改。你不能在应用程序包中修改数据文件,因为iOS应用程序是代码签名的,在应用程序包中修改数据文件会使应用程序的签名失效,使得你的应用程序无法启动。将打算修改的数据文件复制到Application Support(或者其它可写的目录)目录下进行修改是唯一安全的方式。

应用程序临时被打断时应该做什么

基于警报的打断会导致你的应用程序临时性的失去控制。这种情况下,你的应用程序仍然运行在前台,但是不接收任何来自系统的触摸事件(但是会继续接收推送通知等其他类型的时间,比如加速度计时间等)。你应该在applicationWillResignActive:方法中进行如下操作来处理这种情况:

  • 保存数据以及任何相关的状态信息。
  • 停止计时器和其他周期性任务。
  • 停止任何进行的数据请求任务。
  • 不要创建任何新的任务。
  • 停止视屏播放(除了通过AriPlay播放的视屏)
  • 如果你的应用程序是游戏的话,是游戏进入暂停状态。
  • 提高OpenGL ES 帧速率。
  • 暂停执行非关键代码的任何调度队列或操作队列。 (可以在不活动的情况下继续处理网络请求和其他时间敏感的后台任务)

当你的应用程序返回活动状态时,在applicationDidBecomeActive:方法中应该进行与applicationWillResignActive:相反的操作步骤。因此,一但重新活动,你的应用程序应重新启动计时器,恢复调度队列,并再次调低OpenGL ES帧速率。 但是,游戏不应该自动恢复,它们应该保持暂停,直到用户选择恢复它们为止。

当用户按下睡眠或唤醒按钮时,含有NSFileProtectionComplete保护选项的文件的应用程序必须关闭这些被保护文件的任何引用。对于设置了相应密码的设备,按下睡眠或唤醒按钮时应该锁定屏幕并强制系统丢弃对拥有完全保护文件的解密密钥。当屏幕锁定时,任何尝试访问相关文件的操作都会失败。所以你如果有这样的文件,你应该在applicationWillResignActive:方法中关闭对它们的任何引用,在applicationDidBecomeActive:中打开新的引用。

重要提示: 你应该总是在适当的时候保存用户数据。虽然你可以使用应用程序状态转换来强制对象将为保存的变更写入磁盘,但是合适的做法是永远不要等到状态转换时才去保存数据。

Responding to Temporary Interruptions - 响应临时打断

当基于警报的打断发生时(比如打进电话),应用程序暂时进入非活动状态已便系统可以提示用户如和继续操作。应用程序保持在这个状态直到用户拒绝了这个警报,这时应用程序会返回前台进入活动状态或进入后台。

以横幅形式显示的通知不会像基于警报的通知那样是你的应用程序进入非活动状态。尽管横幅放置在你应用程序窗口的顶部边缘,但是你的应用程序还是能够继续接收触摸事件。然而如果用户下拉横幅以便查看通知中心,你的应用程序就会像基于警报的打断发生时那样进入非活动状态。你的应用程序保持在非活动状态直到用户退出通知中心或启动另一个应用程序,这时,你的应用程序相应的会进入非活动转台或后台。

按下睡眠或唤醒按钮是另一种类型的可以导致你的应用程序暂时进入非活动状态的打断。当用户按下这个按钮,系统会使触摸事件变得不可用并让应用程序进入后台,同时将applicationState的值设置为UIApplicationStateBackground并锁定屏幕。

应用程序在前台时做什么

当你的应用程序返回前台进入活动状态时,你可以重新启动在进入后台时停止的任务。移动到前台时出现的步骤如下图所示,applicationWillEnterForeground:方法应该撤消在applicationDidEnterBackground:方法中完成的任何内容,并且applicationDidBecomeActive:方法应该继续执行与启动时相同的激活任务。

Be Prepared to Process Queued Notifications - 准备处理通知队列

一个处于挂起状态的应用程序必须做好在返回前台或进入后台执行状态时处理任何在队列中的通知。处于挂起状态的应用程序不执行任何代码,因此不能处理通知引发的屏幕方向改变,时间改变,偏好改变以及其它会影响应用程序的外观和状态的改变。为了确保这些改变不会丢失,系统将相关的通知放入队列并在应用程序开始执行代码(无论在前台还是后台)时分发通知给它。为了防止应用程序在恢复通知时变得超负荷,系统会将事件合并,并提供一个单一的通知(每种相关类型),反映自您的应用程序被挂起以来的净变化。

下表列出了分发给你的应用程序的可以合并的通知。这些通知的大多数都直接分发给已经注册的观察者。

Event Notifications
An accessory is connected or disconnected. EAAccessoryDidConnectNotification EAAccessoryDidDisconnectNotification
设备方向改变 UIDeviceOrientationDidChangeNotification除了这个通知,视图控制器自动的改变自己的方向。
重要的时间改变 UIApplicationSignificantTimeChangeNotification
电池状态改变 UIDeviceBatteryLevelDidChangeNotification UIDeviceBatteryStateDidChangeNotification
The proximity state changes. UIDeviceProximityStateDidChangeNotification
被保护的文件的状态的改变 UIApplicationProtectedDataWillBecomeUnavailable UIApplicationProtectedDataDidBecomeAvailable
内建显示器连接或失去连接 UIScreenDidConnectNotification UIScreenDidDisconnectNotification
屏幕显示模式改变 UIScreenModeDidChangeNotification
通过设置应用程序改变了应用程序的设置 NSUserDefaultsDidChangeNotification
当前语言或本地化设置改变 NSCurrentLocaleDidChangeNotification
用户的iCloud账户状态改变 NSUbiquityIdentityDidChangeNotification

通常在任何触摸事件或用户输入事件之前,在主线程中分发队列化的通知。大多数的应用程序应该足够快地处理这些事件,避免在重启是导致可观察到的延迟。

应用程序返回前台时也会接收到要更新自从上次更新以来被标记为dirty的视图的通知。一个运行在后台的应用程序仍然能调用setNeedsDisplaysetNeedsDisplayInRect:方法来请求更新视图。然而,因为这些请求更新的视图不可见,系统合并了这些请求并在应用程序进入前台后才更新它们。

Handle iCloud Changes - 处理iCloud改变

当iCloud的状态发生改变时,系统会发送一个NSUbiquityIdentityDidChangeNotification通知给你的应用程序。用户登入或登出iCloud账号,关闭了文档和数据的同步,都会引起iCloud状态的改变。这个通知表示应用程序应该更新缓存和与iCloud有关的用户界面元素。

如果你的应用程序已经提示了用户是否要在iCloud存储文件的话,不要在iCloud状态发生改变时再次提醒。在第一次提醒了用户后,将用户的选择保存在本地的偏好设置中。

Handle Locale Changes - 处理本地化改变

如果用户在你的应用程序挂起时改变了当前的本地化方案,当你的应用程序返回前台时,你可以使用NSCurrentLocaleDidChangeNotification通知来强制更新包含了对本地化方案敏感的信息,比如日期,时间和数字。当然,最好的避免发生本地化相关的问题的方法是用能简单更新视图的方法来编写代码:

  • 使用autoupdatingCurrentLocale类方法当你检索到NSLocal对象。这个方法返回一个可以自动更新自己来响应本地化方案改变的本地化对象,所以你永远不需要重新创建它。然而,当本地化方案发生改变时,你仍然需要更新包含来自于当前本地化方案的信息的视图。
  • 重新创建任何缓存的日期和数字格式,无论当前本地化方案何时发生变化。

Handle Changes to Your App’s Settings - 处理偏好设置的改变

如果你的应用程序含有被设置应用程序管理的设置选项,你应该监测NSUserDefaultsDidChangeNotification通知,因为用户可以改变这些设置当你的应用程序被挂起或在后台。你可以使用这个通知来响应并处理在这些设置上的重要改变。

一旦收到NSUserDefaultsDidChangeNotification通知,你的应用程序应该重新加载任何相关的设置,如果需要,恰当地重置用户界面。

应用程序在后台时做什么

当应用程序从前台转为后台执行时,使用你的代理对象的applicationDidEnterBackground:方法来做:

  • 准备应用程序的照片。当你的applicationDidEnterBackground:返回时,系统会对你的应用程序的用户界面拍照并用这个照片来做过度动画。如果你的应用程序里的视图包含敏感信息,你应该在applicationDidEnterBackground:返回之前隐藏或更改这些视图。
  • 保存任何应用程序状态的相关信息。在进入后台之前,你的应用程序应该已经保存好了所有重要的用户数据。使用转换到后台来保存应用程序状态的最后一分钟更改。

你的应用程序代理对象的applicationDidEnterBackground:方法大约有5分钟的时间来结束任何任务并返回。实际上,这个方法应该可能快的返回。如果这个方法没有在时间耗尽前返回,你的应用程序将会被终止并被移出内存。如果你仍然需要更多的时间来执行任务,调用beginBackgroundTaskWithExpirationHandler:方法来请求后台执行时间,然后在一个次要线程里开始任何长时任务。不管你有没有开始一个后台任务,applicationDidEnterBackground:方法都会在5分钟内退出。

提示: 除了调用applicationDidEnterBackground:方法外,系统还会发送UIApplicationDidEnterBackgroundNotification通知。你可以使用这个通知将清理任务分发给应用程序里的其它对象。

The Background Transition Cycle - 后台转换周期

When the user presses the Home button, presses the Sleep/Wake button, or the system launches another app, the foreground app transitions to the inactive state and then to the background state. These transitions result in calls to the app delegate’s applicationWillResignActive: and applicationDidEnterBackground: methods, as shown in Figure 4-5. After returning from the applicationDidEnterBackground: method, most apps move to the suspended state shortly afterward. Apps that request specific background tasks (such as playing music) or that request a little extra execution time from the system may continue to run for a while longer.

当用户按下Home键,按下睡眠或唤醒按钮,或者系统启动了另一个应用程序,运行在前台的应用程序会转换为非活动状态然后进入后台。这些状态转换会导致调用applicationWillResignActive:applicationDidEnterBackground:方法,如下图所示。从applicationDidEnterBackground:方法返回后,大多数应用程序不久之后就会转换到挂起状态。 请求特定后台任务(如播放音乐)或从系统请求一点额外执行时间的应用程序可能会持续运行一段时间。

Prepare for the App Snapshot - 准备应用程序快照

系统在应用程序代理对象applicationDidEnterBackground:方法返回的不久之前,对应用程序的窗口进行快照。相似的,当应用程序被唤醒执行后台任务时,系统会对应用程序进行一次新的反应改变的快照。

如果在进入后台更改视图时,可以调用主视图的snapshotViewAfterScreenUpdates:方法来强制执行这些更改。在一个视图上调用setNeedsDisplay方法对快照是无效的,因为快照发生在下一个绘制周期之前。调用值为“YES”的snapshotViewAfterScreenUpdates:方法将立即使用机器的底层缓冲区更新快照。

Reduce Your Memory Footprint

每个应用程序应该在进入后台时释放尽可能多的内存。 系统尝试尽可能多地在内存中保留应用程序,但是当内存不足时,会终止挂起的应用程序以回收该内存。 在后台消耗大量内存的应用程序是第一个要终止的应用程序。

实际上,你的应用程序应该在不再需要的时候删除对对象的强引用。 删除强引用使编译器能够立即释放对象,以便可以回收对应的内存。 但是,如果要缓存某些对象以提高性能,则可以等到应用程序转换到后台再删除对它们的引用。

应该尽快删除强引用的对象的一些示例包括:

  • 你创建的图像对象。
  • 可以从磁盘重新加载的大型媒体或数据文件
  • 您的应用程序不需要的任何稍后可以重新创建其他对象。

为了帮助你减少应用程序的内存占用空间,系统会自动清除在应用程序移动到后台时代表应用程序分配的数据。

  • 系统清除所有Core Animation层的后备存储。 此功能不会从应用程序的图层对象中删除内存,也不会更改当前图层属性。 它只是防止这些图层的内容出现在屏幕上,这表明应用程序在后台应该不会发生。
  • 它删除任何系统对缓存图像的引用。
  • 它删除了对其他系统管理的数据高速缓存的强引用。

应用程序生命周期和状态转换操作策略

https://cocoalei.github.io/blogs/2015/10/18/ios-application-life-cycle/

作者

Y2hlbmdsZWk=

发布于

2015-10-18

更新于

2021-09-01

许可协议