iOS 收集我的测试收藏iOS技术收藏

iOS程序启动原理

2015-10-29  本文已影响1723人  ForeverYoung21

一个程序从main函数开始启动。

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

可以看到main函数会调用UIApplicationMain函数,它的四个参数的意思是:

argc: 代表程序在进入main函数时的参数的个数。默认为1。
argv: 代表包含的各个参数。默认为程序的名字。
principalClassName: UIApplication或者它的子类的名字, 如果传入的是nil, 则表示UIApplication的名字, 即@"UIApplication"。
delegateClassName: UIApplication的代理的名字。

在UIApplicationMain函数中,根据传入的UIApplication名称和它的代理的名称,会主要做下面的事情:

现在具体分析一下,通过Storyboard方式加载控制器和代码方式加载控制器。

通过Storyboard

通过Storyboard,主要做了下面的事情(这些事情不需要我们做,是系统自动完成的,在程序启动完成的时候):

通过代码方式

通过代码的方式,需要我们在didFinishLaunchingWithOptions方法中进行加载控制器的相关操作。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    UIViewController *viewController = [[UIViewController alloc] init];
    self.window.rootViewController = viewController;
    // 此时根控制器的view还没有加到self.window上
    [self.window makeKeyAndVisible];
    // 此时根控制器的view加到self.window上
    return YES;
}

其实这里所做和系统所做是一样的。(相当于系统的做法)

UIWindow的补充

window是有层级的,并且可以有多个window同时存在。比如:状态栏就是一个window,键盘也是一个window。

可以通过设置UIWindow的对象的windowLevel属性来调整层级。

self.window.windowLevel = UIWindowLevelStatusBar;

window共有三种等级:UIWindowLevelNormalUIWindowLevelStatusBar UIWindowLevelAlert。如果三种等级同时出现在屏幕上,那么alert在最上面,statusBar在中间,normal则在最下面。

注意:如果一个程序中有多个window,控制器默认会把状态栏隐藏。

解决办法:关闭控制器对状态栏的控制,(为Info.plist增加View controller-based status bar appearance这个key并设置为NO)这样这些window以及状态栏就可以按层级关系正常显示。

上一篇 下一篇

猜你喜欢

热点阅读