当前位置:   article > 正文

ios APP启动原理与自定义UIApplication_ios uiapplicationmain启动自定义页面

ios uiapplicationmain启动自定义页面

iOS APP启动原理

在oc项目中,入口文件是main.m文件,App启动时首先会初始化所有的类,然后再调用main.m中的main函数。

启动过程:

  1. 从类的初始化到main函数的执行
  2. 执行AppDelegate中的- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

main.m代码

  1. /*
  2. UIApplicationMain
  3. 1 创建了 UIApplication 应用对象;
  4. 2 创建了Application delegate(AppDelegate)对象
  5. 3 建立了一个事件循环 (创建了runloop对象,开启事件循环)
  6. 4 读info.plist
  7. 创建一个AppDelegate的window
  8. UIWindowLevelAlert > UIWindowLevelStatusBar > UIWindowLevelNormal
  9. */
  10. int main(int argc, char * argv[]) {
  11. @autoreleasepool {
  12. return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); // 死循环
  13. }
  14. }

虽然main中有return,但其实没有返回任何东西,若return则代表着程序退出。主要原因在于runloop,其内部会有while循环保证程序一直运行。

第一个参数 ——argc,int类型。代表程序启动时的参数个数。默认是1

第二个参数——argv,char[]。代表各个参数的值,默认是程序的名字

第三个参数——principalClassName,NSString类型。主要传UIApplication或其子类的类名对应的字符串。如果nil,就是             UIApplication。(可以自定义UIApplication的子类,处理一些事情如:日志的统计)

第四个参数——delegateClassName,NSString类型。AppDelegate类由编译器自动生成模板。并实现里面的协议以实现我们需要的功能。由于许多配置需要在AppDelegate中进行设置,因此会造成文件代码的臃肿,可以创建APPDelegate的分类,在分类中配置一些第三方库需要的配置参数,或者广告页等,以达到瘦身的目的。

在xcode5之前,通常会写这样一段代码

  1. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  2. self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  3. ViewController * rootVC = [ViewController new];
  4. self.window.rootViewController = rootVC;
  5. [self.window makeKeyAndVisible];
  6. return YES;
  7. }

有了storyboard之后就不需要了。为什么不需要了呢?APPDelegate是如何与ViewController建立联系的。主要还是回到main函数中的UIApplicationMain这个类,在初始化的时候会加载info.plist这个资源文件,如下图所示

在资源文件中Main storyboard file base name 指定了加载Main.StoryBoard作为应用的入口文件,而Main.StoryBoard又与ViewContoller进行了关联,所以不需要做其它操作。

如果我们把这个配置给删除掉,那么则需要在AppDelegate的协议中写上上面那段代码。

 

在swift项目中其实没有main文件。而在APPDelegate.swift中多一个注解@UIApplicationMain,系统会默认将该文件作为UIApplicationMain的第四个参数。如果想要自定义,需要注释掉@UIApplicationMain,然后创建main.swift

  1. import UIKit
  2. import Foundation
  3. UIApplicationMain(CommandLine.argc,
  4. UnsafeMutableRawPointer(CommandLine.unsafeArgv).bindMemory(to: UnsafeMutablePointer<Int8>.self, capacity: Int(CommandLine.argc)),
  5. nil,
  6. NSStringFromClass(AppDelegate.self)
  7. )

这样就OK了。如果不使用自定义的UIApplication,那么创建main.swift文件的意义就不大。

 

自定义UIApplication

UIApplicationMain的第三个参数是UIApplication对象。如果传nil,则会默认调用UIApplication对象。如果我们自定义UIApplication可以提完成我们自定义的。在定义的UIApplication对象我们可以统一处理一些业务,比如日志等

 

  1. import UIKit
  2. class CustomApplication: UIApplication {
  3. //uiapplicton中有与Event相关的api,所以可以利用这些api完成记录行为日志的任务
  4. override func sendEvent(_ event: UIEvent) {
  5. //在这里处理一些统一的逻辑
  6. print("来自UIApplication 的 event")
  7. return super .sendEvent(event)
  8. }
  9. override func sendAction(_ action: Selector, to target: Any?, from sender: Any?, for event: UIEvent?) -> Bool {
  10. //在这里处理一些统一的逻辑
  11. //例如 longinController的,某个action
  12. if target is ViewController && sender is UIButton && NSStringFromSelector(action) == "loginAction"{
  13. //记录日志或者上传服务器
  14. print("来自UIApplication 的 sendAction")
  15. }
  16. return super.sendAction(action, to: target, from: sender, for: event)
  17. }
  18. }

在ViewController中添加一个button,并点击按钮

UIApplication的sendEvent被调用多次,然后sendAction方法被处罚,最后执行button绑定的事件

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/124955
推荐阅读
相关标签
  

闽ICP备14008679号