iOS App生命周期

iOS App生命周期

无论是基于C还是基于Objective-C的程序,程序的入口都是main函数。在iOS中已为你创建好main函数,如下:

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

UIApplicationMain

UIApplicationMain(_:_:_:_:)官网解释为:

Creates the application object and the application delegate and sets up the event cycle.
创建application对象,和application的代理,设置事件循环

该方法有4个参数,着重看后面2个:

  • principalClassName-指定应用程序类名(app的象征),该类必须是UIApplication(或子类)。如果为nil,则用UIApplication类作为默认值
  • delegateClassName-指定应用程序的代理类,该类必须遵守UIApplicationDelegate协议

Programming iOS 10 Dive Deep into Views View Controllers and Frameworks书中有这样的介绍:

1.UIApplicationMain实例化UIApplication,并保留这个实例,作为一个共享的application实例,可通过UIApplication.shared来获取到。然后实例化app的代理类。它保留app的代理类,并把它指定为application实例的代理
2.UIApplicationMain检查app是否使用了main storyboard(通过Info.plist 文件中的UIMainStoryboardFile来确定)。
3.如果使用main storyboardUIApplicationMain实例化UIWindow,并把window实例指派给app代理的window属性。
4.如果使用了main storyboardUIApplicationMain将实例化storyboard的初始控制器。并把这个控制器实例指派给windowrootViewController属性。当控制器成为主window的rootViewController后,它的view将会成为主window的唯一直接子view——主window的根view。 主window中的所有其他view都是根view的子view
5.UIApplicationMain调用app代理的application(_:didFinishLaunching- WithOptions:)方法
6.此时app的界面还不可见,直到window成为app的关键window。如果使用了storyboard,UIApplicationMain将调用window实例的makeKeyAndVisible方法

app运行起来后,可以有多种方式来引用window

  • 如果UIView在界面中,其window属性会自动的指向这个window。可通过UIViewwindow属性来判断view是否被嵌入到了window中,如果其window值为nil,则对用户来说则不可见
  • app代理的window属性也维持着对window的引用。可通过如下的方法引用window

    let w = UIApplication.shared.delegate!.window!!
    //或者
    let w = (UIApplication.shared.delegate as! AppDelegate).window!
  • 共享的application的keyWindow属性也有引用window

    let w = UIApplication.shared.keyWindow!

    但是这个引用,却不是固定的,因为系统可以创建临时窗口并将它们作为应用程序的关键窗口

UIApplication

App Programming Guide for iOS中,如下的图,iOS App中的关键对象
1

UIApplication的核心作用是提供了 iOS 程序运行期间的控制和协作工作。

每一个程序在运行期必须有且仅有一个 UIApplication(或则其子类)的一个实例。在程序开始运行的时候,UIApplicationMain 函数是程序进入点,这个函数做了很多工作,其中一个重要的工作就是创建一个 UIApplication 的单例实例。在你的代码中你,你可以通过调用 [UIApplication sharedApplication] 来得到这个单例实例的指针。

UIApplication 的一个主要工作是处理用户事件,它会起一个队列,把所有用户事件都放入队列,逐个处理,在处理的时候,它会发送当前事件 到一个合适的处理事件的目标控件。此外,UIApplication 实例还维护一个在本应用中打开的 window 列表(UIWindow 实例),这样它就 可以接触应用中的任何一个 UIView 对象。

UIApplication 实例会被赋予一个代理对象,该代理遵循UIApplicationDelegate协议,以处理应用程序的生命周期事件(比如程序启动和关闭)、系统事件(比如来电、记事项警告)等等。

app可以通过openURL(_ :)方法处理资源,如电子邮件或图像文件。 例如,使用电子邮件URL调用此方法的应用程序会导致邮件应用程序启动并显示消息。

UIApplication对象可以执行如下的操作:

1.临时挂起传入的触摸事件(beginIgnoringInteractionEvents())
2.注册远程通知(registerForRemoteNotifications())
3.触发撤消重做UI(applicationSupportsShakeToEdit)
4.是否有已安装应用可以处理URL Scheme(canOpenURL(_:))
5.扩展应用程序的执行,以便它可以在后台完成一个任务(beginBackgroundTask(expirationHandler:),beginBackgroundTask(withName:expirationHandler:))
6.发送和取消本地通知(scheduleLocalNotification(:), cancelLocalNotification(:))
7.协调远程控制事件的接收(beginReceivingRemoteControlEvents(), endReceivingRemoteControlEvents())
8.执行应用程序级别的状态恢复任务

绝大数app并不需要继承UIApplication,而是使用app的代理来管理系统和应用程序之间的交互
如果你的应用程序必须在系统执行之前处理传入事件(这是非常罕见的情况),则可以实施自定义事件或动作分派机制。为此,可以继承UIApplication,并重写 sendEvent(_:)方法,和/或者sendAction(_:to:from:for:) 方法, 对于你截取的每个事件,在处理事件后通过调用[super sendEvent:event]将其分派回系统

主RunLoop

app的 main run loop处理所有用户相关的事件。UIApplication 对象在启动时设置main run loop,并使用它来处理事件和处理view界面的更新。顾名思义,主运行循环是运行在主线程上的,这样可确保用户相关事件按接收顺序进行连续处理。

下图显示了主运行循环的体系结构以及用户事件是如何导致应用程序执行操作的。 当用户与设备交互时,与这些交互相关的事件由系统生成并通过由UIKit设置的特殊端口传递给应用。 事件在应用程序内部排队,并逐个派发到主运行循环中执行。 UIApplication对象是接收事件的第一个对象,并决定需要做什么。 触摸事件通常分派给主窗口对象,然后将其分派到发生触摸的视图。

2

iOS应用可以传递不同类型的事件。一些是在主运行循环中传递,而有些却不是。一些事件被发送给代理对象或者你提供的block

某些事件(如触摸和远程控制事件)由应用程序的responder对象处理。 响应者对象在您的应用程序中无处不在。 (UIApplication对象,视图对象和视图控制器对象都是响应者对象的示例。)

生命周期

可参考Managing Your App’s Life Cycle

app总在如下5种状态中的一种

3

可参考UIApplicaion 生命周期

其它

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值