Application加载ViewController过程探究

来源:互联网 发布:萌叔装机 知乎 编辑:程序博客网 时间:2024/05/16 06:45
1.Main 函数是一切的起点,OC程序都从main文件开始.
Main函数中如果是如下,那就讲进入AppDelegate中去进一步寻找下一步加载的组件.

int main(int argc, char * argv[]) {
   
@autoreleasepool {
       
returnUIApplicationMain(argc, argv, nil,NSStringFromClass([AppDelegateclass]));
    }
}

而如果都为nil.不返回Appdelegate的.那么多半都是之前的老项目,加载的Xib文件
int main(int argc, char * argv[]) {
   
@autoreleasepool {
        returnUIApplicationMain(argc, argv,nil,nil));
    }
}

2.根据加载方式的不同,有三种不同的入口
AppDelegate设置
main 函数-> main 中的代理类(AppDelegate)->代理类中的 didFinishLaunchingWithOptions 方法->设置self.window的rootViewControl

xib方式
plist 中找.plist 文件已经设置了绑定的 xib 文件,而 appdelegate 是绑定在 xib 文件上的.

Storyboard
从plist中找到自动加载的 Storyboard 文件->Storyboard 中找到第一个加载的 viewController.

最基本的当然是直接从AppDelegate中设置RootViewController. Storyboard/xib设置差异不大,设置之后可以替代在AppDelegate设置;






3.详细
Applegate中设置
1.AppDelegate的关联.
main.m 中UIApplicationMain返回 AppDelegate的.直接找到对应的 appdelegate.

2.直接在AppDelegate的方法 application:didFinishLaunchingWithOptions:里设置RootViewController
self.window = [[UIWindowalloc]initWithFrame:[[UIScreenmainScreen]bounds]];
self.window.rootViewController = revealController;
[self.windowmakeKeyAndVisible];


Xib方式
1.plist文件中设置了”Main nib file base name”属性时,项目自动从就从所需属性的 Xib文件 中开始加载.

2.AppDelegate的关联.
main.m文件中UIApplicationMain(argc, argv, nilnil); 没有返回AppDelegate.appdelegate 是绑定在 xib 文件上的.
main.m 中UIApplicationMain有返回 AppDelegate 的.(没有在plist 中设置的.)直接找到对应的 appdelegate.

storyboard 
1.plist文件中设置了”Main storyboard file base name”属性时,项目自动从就从所需属性的 storyboard 中开始加载.

UIApplication 会自动加载这个被命名的 Storyboard 文件,并把它第一个视图控制器显示到 UIWindow 中(AppDelegate中自带). 


什么是UIWIndow
使用storyboard,AppDelegate继承自UIResponder(触发响应事件),并且有一个 UIWindows 属性。

UIWindow是一种特殊的UIView,通常在一个app中只会有一个UIWindow.

iOS程序启动完毕后,创建的第一个视图控件就是UIWindow,接着创建控制器的view,最后将控制器的view添加到UIWindow上,于是控制器的view就显示在屏幕上了.


一个iOS程序之所以能显示到屏幕上,完全是因为它有UIWindow.也就说,没有UIWindow,就看不见任何UI界面.

2.在StoryBoard文件中设置关联的ViewController. 应用就会从这个ViewController开始.

3.AppDelegate的关联.
main.m 中UIApplicationMain有返回 AppDelegate.直接找到对应的 appdelegate.




------------------------------------------------------------------------------------------------------
扩展阅读: 没有MainWindow.xib文件, Storyboard是如何被加载的呢?
1.在xib中,AppDelegate不是main文件去绑定的.而是和Xib文件绑定到一起的.

让我们来看一下应用的delegate文件, 打开AppDelegate.h, 你将会看到如下内容:

#import <UIKit/UIKit.h> @interface AppDelegate : UIResponder <UIApplicationDelegate> @property (strong, nonatomic) UIWindow *window; @end

要使用Storyboard,你的应用代理对象就必须继承UIResponder(以前都是直接继承自NSObject),并且还有一个UIWindow属性(和以前相比,这个属性不再是一个IBOutlet)。

如果你再看一下 AppDelegate.m , 你会发现它没有做任何事情, 所有的方法都是空的。 即使是 application:didFinishLaunchingWithOptions: 方法, 也只不过简单的返回了一个YES。 在以前,这里会把主视图控制器的视图添加到window上面,或者将window设置到rootViewController属性上面,但是现在,这些都 不需要了。

这个秘密就在于Info.plist文件中, 点击Ratings-Info.plist文件(在Supporting Files分组中), 你将会看到下面的内容:

在基于nib的项目中,这里会有一个名为NSMainNibFile键,或者叫”Main nib file base name”,  它会告诉UIApplication去加载MainWindow.xib, 然后把它关联到应用中。 而我们现在的Info.plist已经没有这些设置了。

Storyboard应用会使用一个叫做UIMainStoryboardFile的键,或者叫做“Main storyboard file  base name”, 来指定应用启动时要加载的Storyboard名称。 当检测到这个设置后,UIApplication将会加载 MainStoryboard.storyboard 文件,并且自动实例化其中的第一个视图控制器, 同时把它的所有视图放到一个新的UIWindow对象中。 不需要写任何代码。

你也可以在Target Summary中看到这些:

这里面有一个新的iPhone/iPod Deployment Info选项让你来选择是使用Storyboard还是nib文件来启动应用。

为了保持教程的完整性,让我们再来看看main.m里面有什么:

#import <UIKit/UIKit.h> #import "AppDelegate.h" int main(int argc, char *argv[]){        @autoreleasepool {                return UIApplicationMain(argc, argv, nil,                         NSStringFromClass([AppDelegate class]));    }}

在以前 UIApplicationMain() 函数的最后一个参数是一个nil值,现在他是NSStringFromClass([AppDelegate class])。


和使用MainWindow.xib最大的不同就是,应用代理不是Storyboard的一部分。因为应用代理不再从nib文件中加载,我们就必须告诉UIApplicationMain我们的应用代理的名字,否则就找不到它了。

0 0
原创粉丝点击