IOS app生命周期

报着请教的态度,开始写写IOS的博客,希望大家共同学习,共同进步。。。。

自己的作图都加上了HJC的水印。。 不是自己的作图就没有HJC的水印。

 

IOS知识点:

1、对IOS的特性有深刻理解(如对象生命周期、内存管理、协议、特性、GCD、blocks、CoreAnimation、cocoa touch框架、runtime机制 等)

2、iOS性能优化和内存优化、代码调试和调优和相关工具(如:Instruments)、集成工具。

3、多线程、网络通信(如http、socket、UDP)、数据持久化(常用的4种)

4、设计模式,如KVO、单例、适配器、策略、代理、工厂、、

5、界面UI(如storyboard、Nib)、各种UI控件,能自定义UI控件、UI构架

6、架构设计,熟悉第三方库、开源组件的使用(如:sdwebimage、AFNetwork、ASI、Three20),并能开发第三方组件

7、代码质量:Code Review、单元测试、自动化测试

8、熟悉swift 

9、熟练使用Xcode开发工具,包括工程配置(如证书配置、调用第三方库等)、熟练使用git、svn等工具

10、精通常用数据结构和算法

11、动画:cocos2d、Unity3D

 

一、 app生命周期---app的5种状态

ios app有5种状态,分别是:

1、Not running未运行:app没启动或被迫终止。

2、Inactive未激活:当前应用正在前台运行,但是并不接收事件(当前或许正在执行其它代码)。一般每当应用要从一个状态切换到另一个不同的状态时,中途过渡会短暂停留在此状态。唯一在此状态停留时间比较长的情况是:当用户锁屏时,或者系统提示用户去响应某些(诸如电话来电、有未读短信等)事件的时候。

3、Active激活:当前应用正在前台运行,并且接收事件。这是应用正在前台运行时所处的正常状态。

4、Backgroud后台:程序在后台而且能执行代码,大多数程序进入这个状态后会在在这个状态上停留一会。时间到之后会进入挂起状态(Suspended)。经过特殊的请求后可以长期处于Backgroud状态。

5、Suspended挂起:程序在后台不能执行代码。系统会自动把程序变成这个状态而且不会发出通知。当挂起时,程序还是停留在内存中的,当系统内存低时,系统就把挂起的程序清除掉,为前台程序提供更多的内存。

技术分享

需要注意的一点是:对于从Not running状态直接进入到background状态的应用,在启动进入到background状态时,如果应用有界面,系统仍然会加载用户界面文件,只是不会显示在应用的window上面。
    为了在程序中确定你的程序是进入到了foreground还是background,你可以在application:didFinishLaunchingWithOptions:   方法中检测UIApplication类对象的applicationState属性,如果应用进入到了foreground,则属性值为UIApplicationStateInactive,如果进入到了background,则为UIApplicationStateBackground。

检测示例代码:

UIApplicationState state = [UIApplication sharedApplication].applicationState;
    return (state==UIApplicationStateActive || state==UIApplicationStateInactive );

 

二、app生命周期---执行流程

技术分享

 

application:didFinishLaunchingWithOptions:   这是程序启动时调用的函数。

applicationDidBecomeActive:  应用在准备进入前台运行时执行的函数。

applicationWillResignActive:   应用当前正要从前台运行状态离开时执行的函数。

applicationDidEnterBackground: 此时应用处在background状态,并且没有执行任何代码,未来将被挂起进入suspended状态。

applicationWillEnterForeground:  当前应用正从后台移入前台运行状态,但是当前还没有到Active状态时执行的函数。

applicationWillTerminate:  当前应用即将被终止,在终止前调用的函数。如果应用当前处在suspended,此方法不会被调用。

 

 

按home键:

applicationWillResignActive

applicationDidEnterBackground

 

1、当URL请求到达时,如果你的应用没在正在运行,则会被启动并且移到前台运行以打开URL。

application:didFinishLaunchingWithOptions:

application:openURL:sourceApplication:

applicationDidBecomeActive

 

2、当URL请求到来时,如果你的应用正在background运行或被suspended,它将会被移到前台以打开URL。 

从第三方分享回来:

applicationWillEnterForeground

application:openURL:sourceApplication:

applicationDidBecomeActive

 支持自定义URL模式的应用,可以在应用启动和去处理URL之前,这个过程之间指定不同的启动画面图像。具体细节,请看Apple官方文档iPhoneAppProgrammingGuide.pdf第85页,“Providing Launch Images for Custom URL Schemes”。

 

3、notification,特指显示banner方式的notification,并不会像上面的中断一样使当前处于active状态的应用切换到Inactive状态。此类通知的banner放置在你的应用窗口的上边沿之上,所以你的应用依然处在active状态,并且继续像以前一样接收touch events。但是,如果用户拉下banner去呈现通知中心内容时,当前应用将会和上面基于警告的中断一样切换到inactive状态。

 

在通话过程中,调整你的应用的UI:

当用户正在接电话,并且返回你的应用继续保持通话,此时状态栏的高度应该增加以反应用户正在通话的事实。相似的,当用户结束通话时,状态栏的高度应该缩减恢复常规高度。处理状态栏高度变化的最好方法是使用view controllers去管理你的应用views。当状态栏frame size改变时,view controllers会自动调整它们所管理的所有内部视图。

如果你的应用因为某些原因而没有使用view controllers,则你应该手动响应状态栏frame size的变化,具体即通过注册UIApplicationDidChangeStatusBarFrameNotification通知来实现。通知处理函数handler应该获取状态栏的高度并且使用这些数据来适度调整当前应用所包含视图的高度。

 

4、应用切向后台background时应该做什么:

应用可以在applicationDidEnterBackground:方法中做些切向background状态前需要做的一些准备工作,当切向background状态时,所有的应用需要做以下事情:

(1)应用界面快照。当applicationDidEnterBackground:方法返回时,系统保存应用界面的快照,并且使用快照图片作为转换动画。如果在你的应用界面中有涉及到敏感信息的视图,则你应该在applicationDidEnterBackground:方法返回前隐藏或者修改这些视图。

(2)保存用户数据和应用状态信息。所有没有保存的改变都应该在切向background状态前写入磁盘以保存。这一步是必须的,因为你的应用在后台时很有可能因为多种其它原因而被很快kill掉。根据需要你可以在background thread后台线程中执行这些操作。

(3)释放尽可能多的内存资源。

applicationDidEnterBackground:方法允许最多有5秒的时间去完成任何任务然后返回。实际中,此方法应该尽可能快的返回。如果在时间到期之后,此方法没有返回,则应用即被kill掉,并且清除所占用的内存。如果你的应用确实需要更多的时间去执行任务,可以调用beginBackgroundTaskWithExpirationHandler:方法请求后台执行时间,然后启动一个能长期执行任务的线程。无论你是否启动一个执行后台任务的线程,applicationDidEnterBackground:方法都必须在5秒后退出。

注:UIApplicationDidEnterBackgroundNotification通知也会发送,以让应用对此通知感兴趣的部分知道当前应用正切向background状态。你的应用中的对象可以使用默认的通知中心注册这个通知。

 

5、前台应用在使用系统资源和硬件时 比后台应用 具有更高的优先权。当应用切向background时尤其要遵循以下几点:

(1)不要在应用代码中调用任何OpenGL ES的东西。

(2)在应用挂起suspended之前取消所有Bonjour相关的服务。如果你的应用不关掉这些和Bonjour相关的服务,当应用被挂起的时候,系统会自动帮你关掉这些服务。

(3)在基于网络sockets的应用中,需要处理连接失败的情况。当应用从后台退出恢复执行时,如果遇到sockets使用错误,简单的重建socket连接即可。

(4)在切向background状态前保存应用状态。在低内存告警时,后台应用可能会被清除出内存以释放空间。处于suspended状态的应用被优先清除内存,并且在被清除前不会给出任何通知。

(5)当切向后台时,释放所有不再需要的内存。如一个很大的内存缓存对象(比如图像),则切入后台前,释放所有的对这些缓存对象的引用。

(6)在被挂起前停止使用系统共享资源。使用系统共享资源(比如Address Book或Calendar Data)的应用,在被挂起前必须停止对这些共享资源的使用。你的应用在被挂起后还没有停止对这些共享资源的使用,则应该将被kill掉。

(7)避免更新应用窗口和视图。尽管在后台创建和操纵窗口和视图对象并不会导致应用被kill掉,但是可以将这些工作推迟到应用返回前台时执行。

(8)响应外部附件连接和失去连接通知。针对和外部附件有通信的应用,当应用切向background状态时,系统会发送一个disconnection通知。应用必须注册此通知并且使用它去关掉当前的附件访问session。当应用返回foreground时,会有一个与之匹配的通知被发送,给应用提供重新建立session的机会。

(9)切向后台时,清除行为警告相关的资源。为了在应用相互切换之间保存应用上下文,当应用切向后台时,系统并不自动dismiss action sheets(UIActionSheet)和alert views(UIAlertView)。对于运行在iOS4.0版本之前的应用,在退出时action sheets和alerts仍然被dismiss掉,以让应用的取消处理函数有机会去运行。

(10)切向后台时,移除所有敏感视图信息。因为系统会快照应用界面并且生成应用切换动画,所以带有敏感信息的视图或窗口必须隐藏或移除。

(11)应用在后台运行时执行最少量化的工作。系统给后台运行的应用的执行时间和给前台运行的应用相比,通常非常有限。如果应用在后台播放音频或者监测位置变化,则应用应该仅关注此任务,所有不必要的任务都应该被推迟。在后台执行时间过长的应用会被系统throttled back或者直接被kill掉。

 

 

6、后台应用的内存使用:

当手机内存即将耗尽时,系统会终止那些挂起suspended的应用以回收内存。然而那些消耗很大数量的内存同时又处于后台background运行的应用会优先被终止。

下面是一些需要回收的对象的例子:

(1)缓存的图像对象

(2)比较大的多媒体文件或数据文件,这些文件可以从磁盘重新装载。

(3)任何应用当前不再需要的对象,并且这些对象后面又可以很容易重新创建。

为了帮助您的应用程序,减少其内存占用,系统会自动释放出许多幕后用于支持您的应用程序的对象。例如:

(1)释放所有的核心动画层的后备存储,以避免这些层继续在屏幕上显示,同时又不改变当前层的属性。并且并不释放层对象自已。

(2)移除所有对缓存图像的引用。(如果应用没有对这些图像强引用,则他们随后即被移除内存)

(3)释放一些系统管理的其它的数据缓存。

 

7、返回前台foreground

1)在应用切向前台被唤醒时处理通知队列

如方向改变、时间改变、偏好改变、以及其它的影响应用的外观的行为或状态等等,系统将这些相关的通知入队列,并且当应用恢复foreground或background重新执行代码时,立即将这些通知发往应用。为了防止应用恢复时因为通知过多而过载,系统会合并事件并且仅传递一个能够反应自从应用被挂起有网络改变的单个通知。

具体通知合并规则如下表所示:

技术分享

通知队列典型的在任何触控事件和用户输入之前被投递向应用的主运行循环main run loop。大多数应用应该能够足够快的处理这些事件。然而,如果发现你的应用在从后台恢复时看起来明显呆滞,则可以使用Instruments去确定是否是通知处理代码正在运行而造成了延迟。

一个应用在返回前台时也会接收所有自从上更新后被标记为dirty的视图的更新通知。处于后台background运行的应用也可以调用setNeedsDisplay或setNeedsDisplayInRect:方法去请求视图更新。然而,因为这时界面不可见,所以系统合并这些请求并且只有当应用恢复前台后才去更新视图。

(2)从容的处理本地改变

当应用处于挂起suspended状态时,如果用户改变了当前语言设置,则当应用返回前台的时候可以使用NSCurrentLocalDidChaneNotification通知来强制任何包含本地敏感信息(像日期、时间、数字等等)的视图进行更新。当然,避免本地信息相关的事件处理的最好的方法还是以那种更容易更新视图的方式来写更新视图的代码。比如:

a.使用autoupdatingCurrentLocal类方法来检索NSLocal对象。此方法返回一个本地对象,该对象响应本地改变并且自动更新自已。所以,你不需要再去重新创建它。然后,当本地信息改变时,你的应用仍然需要去刷新那些包含本地信息的视图。

b.无论任何时候本地信息改变时都去重新创建缓存日期或者数字格式对象。

(3)响应应用设置改变

如果应用包含被Settings应用所管理的设置,则应用应该关注NSUserDefaultsDidChangeNotification通知。

 

8.应用终止

如果应用将被终止时正在前台或后台运行,系统将会调用应用代理的applicationWillTerminate:方法 保存用户数据或应用状态信息,该方法最长运行时限为5秒,过期应用即被kill掉并且移除内存。

注:处于suspended状态的应用被终止时不会有任何通知。但是如果应用当前正在后台background运行,则当应用要被终止时,系统会调用应用代理的applicationWillTerminate:方法。应用不可以在此方法中申请额外的后台执行时间。

 

9.主运行循环main run loop

UIApplication对象在应用启动时安装主运行循环并且使用此循环去处理事件和处理基于视图的界面更新。该主运行循环是在应用的主线程app‘s main thread中运行的。以此保证所有用户事件是按照它们被接收时的顺序串行的执行。

当用户和应用交互时,和这些交互相关的事件由系统自动产生并且借助UIKit设定的特殊端口传递给应用。事件在应用内部以队列的形式存在并且一个一个的被分发到应用的主运行循环去执行。UIApplication对象是第一个接收事件的对象,并且决定需要如何处理事件。触控事件通常被分发到应用的主窗口对象,并且最终分发到发生该触控事件的视图上面。其它的事件传递也许会经过各种各样的应用对象而与触控事件传递稍微有所不同。

技术分享

在iOS应用中可以传递很多类型的事件。最常见的事件列在下表中:

技术分享

技术分享

这些事件类型中的大部分通过应用的主运行循环进行传递,但是还有一些并不是的。例如:accelerometer事件直接被传递到应用指定的accelerometer代理对像。关于系统如何处理大多数类型事件,包括touch、remote control、motion、accelerometer,以及gyroscopic事件,详见Event Handling Guide for iOS.

一些像触控、远程控制类的事件,通常被应用的响应对象处理。响应对象存在于应用的任何地方。(UIApplication对象,view对象,view controller对象等等都是响应对象的例子)。大多数事件是以特定的响应对象为目标,但是也可以被传递给其它的响应对象(借助响应链),例如:一个不处理任何事件的view可以将事件传递给它的父view或传递给view controller。

发生在controls类的视图(例如button)上的事件的处理过程和发生在其它类型的views上的触控事件处理过程有些不一样。因为发生在control类的对象上面的交互行为只有非常有限的几种,因此这些交互重新打包进active message并且传递给合适的目标对象。  这种target-action的设计模式,使应用通过control类型的view对象去触发一段自定义代码的执行变得非常容易。

 

 

 

借鉴的文章:http://blog.csdn.net/duanyipeng/article/details/7101829

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。