IOS应用程序生命周期
前期准备工作
当程序被加载时,第一件事 就是系统打开程序的 Info.plist
,通过这个文件 系统知道编译好二进制文件的位置,并且加载。
在编译好代码,程序通常有一个前期准备接口–pre-prepared windows, controls, and screens,在编译时候,这些同城在一个 nib 文件中中。在开始程序运行的时候,lanched screen 文件被首先加载到内存中。
软后,程序打开nib 文件,和反序列化他的内容。以为程序拆包window,control,和其他文件。并且把他们连接在一起。 The main nib 也包含程序的代理实例。
当一个实例从nib文件中解包是,他会发送 awakeFromNib
消息。这个时候,这个实例开始运行。
Objects that are unpacked from a nib are not sent an init message because they were already initialized when the developer dragged and dropped them into the interface. This is different from objects that are created by calling their constructor in code.
When working with nib files, it’s important to understand that when you add an object to a nib file, that object is created at that mo‐ ment, and “freeze-dried” when the nib file is saved. When the nib file is opened, the object is “rehydrated” and gets back to work. After the object is rehydrated, it is sent the awakeFromNib message to let it know that it’s awake.
To summarize: objects that are loaded from a nib receive the awakeFromNib message. Objects that are created by your code receive the init method.
OSX下程序
当这个时候,应用程序已经准备运行了。application delegate
会执行applicationDidFinishLaunching
方法。。当这个方法完成之后,程序进入run loop.
run loop.
不停监听事件,并发送到相关目的,运行知道程序的退出。
当用户选择其他程序时候 delegate
收到applicationWillResignActive
消息, 意味程序将停止active
状态。 delegate
收到applicationDidResignActive
方法.
当applicatonWillResignActive被调用程序还在屏幕上,当程序不可见的时候,程序delegate receive 收到 applicationDidResignActive
当用户又返回程序时候,程序delegate
收到 applicationWillBecomeActive
(要变成活动) 和 applicationDidBecomeActive
(已经变成活动)
当程序终止的时候,delegate收到了applicationWillTerminate
,这是最后的机会保存文件
IOS程序
IOS平台,由于受到内存有限,在多任务存在很多的限制,同一时刻,其他的程序完全被隐藏的,这个可见的前端程序
and 其他不可见的程序叫做 后台程序
。
在IOS上,当出入打进电话,会打断用户和程序的交互,我们的程序还在前端,但是已经暂停活动状态。 如果用户开始接听电话,我们的程序变为后端程序。
这还有一些其他方法让程序变为不活动。比如从上面往下拉通知任务,或者程序之间的切换。当程序变成不活动的时候,
IOS的生命周期几乎和OSX的一样。 当程序被加载完毕, Info.plist会被检查,二进制文件被找,被加载,变成可执行代码,开始解包main storyboard
的内容
当程序完成加载, delegate
收到 applica tionDidFinishLaunching(_, withOptions:)
后面跟了一个字典的参数,里面包含了为什么和怎样程序别加载。
通常用点击用户点击程序的图标,这样程序被加载。程序还可以通过其他的方式打开,比如一个APP传递文件给其他的APP,或者通过自动以的URL来打开APP。
这个options
,字典包含了描述当前程序启动环境的的信息。
iOS与多任务
IOS平台上的Application是容许运行在后台,但是存在一些限制条件。主要是因为,IOS设备和OSX 设备相比在后面这些地方有很多限制,在CPU能力,内存空间,电池容量。
,
当用户点解Home Button
,或者其他的程序被加载时候,这个应用程序被挂起
,但是没有退出,但是代码停止执行,他的内容被锁住。当程序resumes
,程序从停止的部分还是重新执行。
当程序程序保持挂起状态时候,停止使用CPU资源和定位硬件,然而内存却一直占用,如果其他的APP需要更多的内存资源的时候,APP可能被终止,没有任何提示。
当程序挂起状态的时候,程序不能知道自己要被终止了。所以当Applicaton delegate
当进入background
,我们必须保存重要的数据
func applicationDidEnterBackground(_ application: UIApplication)
func applicationWillEnterForeground(_ application: UIApplication)
applicationDidEnterBackground
我们需要在这个理保存中药数据,原理可能在挂起的状态中终止。
applicationWillEnterForeground
当程序回到屏幕,这里我们有机会设置程序要执行的环境。
程序挂起后,如果前端的程序需要更多的内存,挂起的程序很有可能被终止。所以作为程序的开发者,应该减少占用程序使用的内存(通过释放大内存,卸载图像),来减少被终止的可能。
如果可能,劲量的减少使用内存在
16MB
一下,当程序被挂起,并且内存使用在16MB
,系统会将程序的内存,保存的flash chips
,并且从内存中移除。 当程序resumed
,程序重新加载存在flash chips中内存状态。所以就不会出现应为其他的程序内存的需求,而导致程序被逐出。
进入后台模式
APP可以请求运行后台运行一段时间,这个时间不要超过 10 minutes
,这样APP可以完成下载,保存文件到disk,当 10 minutes
用完以后,APP必须告诉系统已经完成工作,否则程序被终止
(不是挂起,是终止–从内存中完全的消失)
当想要运行后台时候,我们需要些类似下面的代码,
func applicationDidEnterBackground(application : UIApplication)
{
var backgroundTask : UIBackgroundTaskIdentifier! = nil
// Register a background task, and provide a block to run when // time runs out
backgroundTask = application
.beginBackgroundTaskWithExpirationHandler() {
// This block is called when we're out of time; if we haven't
// called endBackgroundTask before this block returns,
// the application is terminated
application.endBackgroundTask(backgroundTask)
backgroundTask = UIBackgroundTaskInvalid
}
let backgroundQueue = NSOperationQueue()
backgroundQueue.addOperationWithBlock() {
// Do some work. You have a few minutes to complete it; by the end,
// you must call endBackgroundTask.
NSLog("Doing some background work!")
application.endBackgroundTask(backgroundTask)
backgroundTask = UIBackgroundTaskInvalid
}
}
IOS7中有2种形式运行后台任务, backgroud fetching
和 background notifications
backgroud fetching
backgroud fetching
被设计成,程序需要的定期更新,比如天气预报,或者社交网络程序(Twitter),如果过程序的backgroud fetching
被启用
application 可以在后端被唤醒,并且在后端去更新一些信息。并且准备好当(当用户把程序带到前端时候)立即显示。
当要使用 backgroud fetching
功能时候,下面几点我们要知道。
-
Select the project in the project navigator, open the Capabilities tab, and
enable Background Fetch
from the Background Modes section. -
Inyourcode,you need to call the
setMinimumBackgroundFetchInterval
function to let iOS know approximately how often to wake your application so it can fetch updates. If you do not set a minimum interval, iOS will default to never waking your application for performing fetches.
实例代码
func application(application: UIApplication,
performFetchWithCompletionHandler completionHandler:
(UIBackgroundFetchResult) -> Void) {
// We have 30 seconds to download some data and process it
var error : NSError? = nil
let data = downloadSomeData(&error)
// Once done, let the OS know whether or not new data was
// retrieved or not, or if there was an error
if error != nil {
completionHandler(UIBackgroundFetchResult.Failed) return
}
// This is a very simple check—your application would
// do something more involved, like compare this data against
// the most recently downloaded data to determine if it's 'new'
if data?.length > 0 {
completionHandler(UIBackgroundFetchResult.NewData)
return
} else {
completionHandler(UIBackgroundFetchResult.NoData)
return
}
}
Background notifications
后台通知允许,程序在后台收到通知并且处理通知后台通知。
后台通知机制,可以让程序在后台时候,用做瞬间消息程序,以及自动跟新会话,和当有新的内容可以去fetched,并提示应用程序。
后台通知操作,和backgroud fetching
也是非常相似,也需要设置,才能够处理通知。
我们将程序的remote notificatio选项打开。
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject])
userInfo是个字典,包含远程通知的数据。
经过我们设置了backgroud fetching的最小的fetch时间间隔,IOS系统会在自己决定合适时间,才唤醒程序 IOS会限制多少个远程通知被发送到设备,
应用程序可以在后台播放音频,可以一直保存的active状态。直到用户使用其他程序播放音频。
应用程序可以后台追踪用户的位置。
VOIP程序(skype)可以周期的检查他的服务器,除非在通话中,不然也不会让他一直运行下去。