iOS:App启动过程详解(相关资源xib等的访问)
2014-07-31 10:06
399 查看
--------------xcode4.2以前(用xib)--------------
应用程序开始的时候没有指定和创建delegete,是通过一个xib文件来创建(MainWindow.xib)
其中File‘s Owner为UIApplication,它的delegate为第三个图标,Button_FunAppDelegate,剩下俩个为Window和初始控制器(delegate类的属性)。通过创建xib,实例化应用程序相应的Delegate类以及Window、控制器。
--应用程序代理类通过xib文件创建,他的相应属性UIWindow、根控制器等也可包括在xib中。
--该xib为《View-based Application》模版,其中有控制器对象。
--《Window-based Application》和《View-based Application》 区别在于有没有第四个图标Button_FunViewController,以及代码 “self.window.rootViewController = self.viewController” 或者“[self.window addSubview: self.viewController.view];”的有无。
--------------xcode4.2以后(without storyboard)--------------
应用程序开始的时候指定了delegete,之后delegate类被创建。
-- 应用程序Info.plist文件不再需要Main nib file base name属性,也不再需要“MainWindow.xib”。
--应用程序代理类不通过xib文件创建,他的相应属性UIWindow、根控制器类等代码创建。
--模板变为《Empty Application》和《Single View Application》
--------------xcode4.2以后(with storyboard)--------------
--.先执行main函数,main内部会调用UIApplicationMain函数
--.UIApplicationMain函数里面做了什么事情:
1.调用UIApplicationMain()函数;
2.创建UIApplication对象;
3.创建UIApplication的delegate对象-----XXAppDelegate;
4.加载Info.plist文件,读取最主要storyboard文件的名称;
5.UIApplication开启一个消息循环
* 每监听到对应的系统事件时,就会通知MJAppDelegate;
6.UIApplication调用相关代理方法;
------------我是分割线------------
7.为应用程序创建一个UIWindow对象(继承自UIView),设置为XXAppDelegate的window属性;
8.加载最主要的storyboard文件,创建白色箭头所指的控制器对象;
9.并且将8步奏里创建的控制器为UIWindow的rootViewController属性(根控制器);
10.展示UIWindow,展示之前会将添加rootViewController的view到UIWindow上面(在这一步才会创建控制器的view)
[window addSubview: window.rootViewControler.view];
------------end------------
问题:上叙7~10猜想成分太大了,而且application:didFinishLaunchingWithOptions 跟加载storyboard文件顺序交叉了,到底它们实际执行顺序是什么?
**用例1**:不使用storyboard,程序启动后进入application:didFinishLaunchingWithOptions方法,该方法内部什么都不实现
用例1分析:程序启动,didFinishLaunchingWithOptions方法里没有加载任何视图(还有window原因,见下面用例)。
**用例2**:不使用storyboard,程序启动后进入application:didFinishLaunchingWithOptions方法,该方法内部创建添加需要显示的内容。
**用例3**:不使用storyboard,程序启动后进入application:didFinishLaunchingWithOptions方法,该方法内部创建UIWindow,并创建添加需要显示的内容。
用例2+用例3分析:当不用storyboard的时候,AppDelegate被创建完之后,它的window属性为空,需要手动创建之。然后再用它。
**用例4**:使用storyboard,程序启动后进入application:didFinishLaunchingWithOptions方法,该方法内部创建添加需要显示的内容
(备注:storyboard里面初始化的控制器为ViewController,并且在相关方法输出了_cmd)
**用例5**:使用storyboard,程序启动后进入application:didFinishLaunchingWithOptions方法,该方法内部创建添加需要显示的内容
分析用例5:当info.plist里面有值时,程序先加载storyboard中的对象,并创建之,之后创建AppDelegate的window,并且将初始控制器赋值给window的rootViewController,然后调用application:didFinishLaunchingWithOptions方法。
说明:
1.window的rootViewController会覆盖windows上的子视图。
2.如果使用storyboard的情况下,[self.window makeKeyAndVisible]方法会在方法application:didFinishLaunchingWithOptions结束后,隐式调用;当然也可以显示调用,window提前显示到了屏幕上。例如上面用例结果1,如果[self.window makeKeyAndVisible]显示写在 NSLog(@"here3");之前,则 输出“TableViewController
: viewDidLoad” 在“here3”之前。
-------结论:
使用storyboard的时候,先创建storyboard里面对象,和appDelegate的window,之后调用相关代理方法didFinish...,之后如果需要再调用[makeKeyAndVisible];
--------------备注--------------
a.关于Application如何查找对应的plist文件? 当一个target创建完,它自动关联了一个plist文件(名字一般是target.plist),如果我们修改了该plist文件名或者该文件被删除,导致target找不到该plist文件,则进入target info界面的时候要要求选择 plist文件,如下图:
b.UIWindow里面有UIScreen,属性,但是创建UIWindow还是用的[UIScreen mainScreen]。
应用程序开始的时候没有指定和创建delegete,是通过一个xib文件来创建(MainWindow.xib)
int main(int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; int retVal = UIApplicationMain(argc, argv, nil, nil); [pool release]; return retVal; }--程序开始-->创建UIApplication实例-->查看应用程序的 Info.plist -->根据Main nib file base name属性,加载xib文件,创建相应类。程序启动调用相应代理方法,详见如下:
其中File‘s Owner为UIApplication,它的delegate为第三个图标,Button_FunAppDelegate,剩下俩个为Window和初始控制器(delegate类的属性)。通过创建xib,实例化应用程序相应的Delegate类以及Window、控制器。
--应用程序代理类通过xib文件创建,他的相应属性UIWindow、根控制器等也可包括在xib中。
--该xib为《View-based Application》模版,其中有控制器对象。
--《Window-based Application》和《View-based Application》 区别在于有没有第四个图标Button_FunViewController,以及代码 “self.window.rootViewController = self.viewController” 或者“[self.window addSubview: self.viewController.view];”的有无。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. //self.window.rootViewController = self.viewController; [self.window addSubview: self.viewController.view]; [self.window makeKeyAndVisible]; return YES; }
--------------xcode4.2以后(without storyboard)--------------
应用程序开始的时候指定了delegete,之后delegate类被创建。
int main(int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; int retVal = UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); [pool release]; return retVal; }程序开始-->创建UIApplication实例-->创建Delegate类,赋给uiApplication的delegate属性,程序启动后调用相应代理方法。
-- 应用程序Info.plist文件不再需要Main nib file base name属性,也不再需要“MainWindow.xib”。
--应用程序代理类不通过xib文件创建,他的相应属性UIWindow、根控制器类等代码创建。
--模板变为《Empty Application》和《Single View Application》
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions { self.window= [[UIWindowalloc] initWithFrame:[[UIScreenmainScreen] bounds]]; //self.viewController= [[<app>ViewController alloc] init]; //self.window.rootViewController = self.viewController; [self.windowmakeKeyAndVisible]; return YES; }
--------------xcode4.2以后(with storyboard)--------------
--.先执行main函数,main内部会调用UIApplicationMain函数
--.UIApplicationMain函数里面做了什么事情:
1.调用UIApplicationMain()函数;
2.创建UIApplication对象;
3.创建UIApplication的delegate对象-----XXAppDelegate;
4.加载Info.plist文件,读取最主要storyboard文件的名称;
5.UIApplication开启一个消息循环
* 每监听到对应的系统事件时,就会通知MJAppDelegate;
6.UIApplication调用相关代理方法;
------------我是分割线------------
7.为应用程序创建一个UIWindow对象(继承自UIView),设置为XXAppDelegate的window属性;
8.加载最主要的storyboard文件,创建白色箭头所指的控制器对象;
9.并且将8步奏里创建的控制器为UIWindow的rootViewController属性(根控制器);
10.展示UIWindow,展示之前会将添加rootViewController的view到UIWindow上面(在这一步才会创建控制器的view)
[window addSubview: window.rootViewControler.view];
------------end------------
问题:上叙7~10猜想成分太大了,而且application:didFinishLaunchingWithOptions 跟加载storyboard文件顺序交叉了,到底它们实际执行顺序是什么?
**用例1**:不使用storyboard,程序启动后进入application:didFinishLaunchingWithOptions方法,该方法内部什么都不实现
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. return YES; }结果:程序启动,屏幕一片漆黑。
用例1分析:程序启动,didFinishLaunchingWithOptions方法里没有加载任何视图(还有window原因,见下面用例)。
**用例2**:不使用storyboard,程序启动后进入application:didFinishLaunchingWithOptions方法,该方法内部创建添加需要显示的内容。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. TableViewController *tableViewController = [[TableViewController alloc]initWithStyle:UITableViewStylePlain]; [self.window addSubview:tableViewController.view]; [self.window makeKeyAndVisible]; return YES; }结果:程序启动,屏幕一片漆黑
**用例3**:不使用storyboard,程序启动后进入application:didFinishLaunchingWithOptions方法,该方法内部创建UIWindow,并创建添加需要显示的内容。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]]; TableViewController *tableViewController = [[TableViewController alloc]initWithStyle:UITableViewStylePlain]; [self.window addSubview:tableViewController.view]; [self.window makeKeyAndVisible]; return YES; }结果:程序启动,显示tableviewController的视图,正常。
用例2+用例3分析:当不用storyboard的时候,AppDelegate被创建完之后,它的window属性为空,需要手动创建之。然后再用它。
**用例4**:使用storyboard,程序启动后进入application:didFinishLaunchingWithOptions方法,该方法内部创建添加需要显示的内容
(备注:storyboard里面初始化的控制器为ViewController,并且在相关方法输出了_cmd)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. NSLog(@"here1"); NSLog(@"%@",self.window); TableViewController *tableViewController = [[TableViewController alloc]initWithStyle:UITableViewStylePlain]; NSLog(@"here2"); [self.window addSubview:tableViewController.view]; NSLog(@"here3"); return YES; }结果:输出,界面显示ViewController的界面
2014-09-20 16:30:22.066 Refer[3253:60b] ViewController : initWithCoder: 2014-09-20 16:30:22.074 Refer[3253:60b] here1 2014-09-20 16:30:22.077 Refer[3253:60b] <UIWindow: 0x14db9020; frame = (0 0; 320 480); hidden = YES; gestureRecognizers = <NSArray: 0x14db9cb0>; layer = <UIWindowLayer: 0x14dbb910>> 2014-09-20 16:30:22.079 Refer[3253:60b] here2 2014-09-20 16:30:22.091 Refer[3253:60b] TableViewController : viewDidLoad 2014-09-20 16:30:22.095 Refer[3253:60b] here3 2014-09-20 16:30:22.104 Refer[3253:60b] ViewController : viewDidLoad分析用例4:tableviewController的界面不显示,可能是被viewController界面覆盖了,还是某种原因。
**用例5**:使用storyboard,程序启动后进入application:didFinishLaunchingWithOptions方法,该方法内部创建添加需要显示的内容
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. NSLog(@"here1"); NSLog(@"%@",self.window); NSLog(@"%@",self.window.rootViewController); TableViewController *tableViewController = [[TableViewController alloc]initWithStyle:UITableViewStylePlain]; NSLog(@"here2"); [self.window setRootViewController:tableViewController]; // or [self.window.rootViewController.view addSubview:tableViewController.view]; NSLog(@"here3"); return YES; }结果:输出,界面显示tableviewController的界面
2014-09-20 16:40:14.135 Refer[3260:60b] ViewController : initWithCoder: 2014-09-20 16:40:14.143 Refer[3260:60b] here1 2014-09-20 16:40:14.146 Refer[3260:60b] <UIWindow: 0x16e5f570; frame = (0 0; 320 480); hidden = YES; gestureRecognizers = <NSArray: 0x16e5fc10>; layer = <UIWindowLayer: 0x16e5f650>> 2014-09-20 16:40:14.148 Refer[3260:60b] <ViewController: 0x16da9be0> 2014-09-20 16:40:14.150 Refer[3260:60b] here2 2014-09-20 16:40:14.153 Refer[3260:60b] here3 2014-09-20 16:40:14.167 Refer[3260:60b] TableViewController : viewDidLoad结果(当执行or里面的语句)输出,界面显示tableviewController的界面
014-09-20 16:43:21.707 Refer[3268:60b] ViewController : initWithCoder: 2014-09-20 16:43:21.716 Refer[3268:60b] here1 2014-09-20 16:43:21.718 Refer[3268:60b] <UIWindow: 0x16d88720; frame = (0 0; 320 480); hidden = YES; gestureRecognizers = <NSArray: 0x16e7a1b0>; layer = <UIWindowLayer: 0x16d8c2b0>> 2014-09-20 16:43:21.720 Refer[3268:60b] <ViewController: 0x16d8a170> 2014-09-20 16:43:21.722 Refer[3268:60b] here2 2014-09-20 16:43:21.731 Refer[3268:60b] ViewController : viewDidLoad // <span style="color:#cc0000;">因为调用到了它</span> 2014-09-20 16:43:21.741 Refer[3268:60b] TableViewController : viewDidLoad 2014-09-20 16:43:21.743 Refer[3268:60b] here3
分析用例5:当info.plist里面有值时,程序先加载storyboard中的对象,并创建之,之后创建AppDelegate的window,并且将初始控制器赋值给window的rootViewController,然后调用application:didFinishLaunchingWithOptions方法。
说明:
1.window的rootViewController会覆盖windows上的子视图。
2.如果使用storyboard的情况下,[self.window makeKeyAndVisible]方法会在方法application:didFinishLaunchingWithOptions结束后,隐式调用;当然也可以显示调用,window提前显示到了屏幕上。例如上面用例结果1,如果[self.window makeKeyAndVisible]显示写在 NSLog(@"here3");之前,则 输出“TableViewController
: viewDidLoad” 在“here3”之前。
-------结论:
使用storyboard的时候,先创建storyboard里面对象,和appDelegate的window,之后调用相关代理方法didFinish...,之后如果需要再调用[makeKeyAndVisible];
--------------备注--------------
a.关于Application如何查找对应的plist文件? 当一个target创建完,它自动关联了一个plist文件(名字一般是target.plist),如果我们修改了该plist文件名或者该文件被删除,导致target找不到该plist文件,则进入target info界面的时候要要求选择 plist文件,如下图:
b.UIWindow里面有UIScreen,属性,但是创建UIWindow还是用的[UIScreen mainScreen]。
相关文章推荐
- iOS:App启动过程详解
- iOS APP启动过程详解
- 毕业设计---相关知识(计算机启动过程详解)
- 005-iOS App程序启动过程
- Info.plist和pch文件的作用,UIApplication,iOS程序的启动过程,AppDelegate 方法解释,UIWindow,生命周期方法
- iOS-程序的启动过程以及相关的注意事项
- iOS应用启动画面以及APP相关图标
- IOS温故而知新(一) 一步一步分析新建App启动过程
- IOS App Icon Size 图标尺寸 LaunchImage iPhone Portrait 启动画面大小 Image资源使用
- 2017年开始今年开始iOS 10设备上的app必须通过https且是TLS 1.2的协议去访问web资源
- Info.plist和pch文件的作用,UIApplication,iOS程序的启动过程,AppDelegate 方法解释,UIWindow,生命周期方法
- IOS App Icon Size 图标尺寸 LaunchImage iPhone Portrait 启动画面大小 Image资源使用
- IOS App Icon Size 图标尺寸 LaunchImage iPhone Portrait 启动画面大小 Image资源使用
- Info.plist和pch文件的作用,UIApplication,iOS程序的启动过程,AppDelegate 方法解释,UIWindow,生命周期方法
- web资源访问过程及http协议详解
- IOS APP 国际化(实现不跟随系统语言,不用重启应用,代码切换stroyboard ,xib ,图片,其他资源)
- Info.plist和pch文件的作用,UIApplication,iOS程序的启动过程,AppDelegate 方法解释,UIWindow,生命周期方法
- iOS app在启动过程的设置图片的规格
- iOS AppDelegate 代理详解(启动,打开App,推送,通知)
- 详解iOS应用程序的启动过程