UIApplicationMain函数

UIApplicationMain函数

1. iOS程序的启动

在C语言中,程序是从main开始执行的, 在一个iOS应用中,也是从main 函数开始执行的.该main函数和C语言中的main函数没有什么不同.不同的是该函数的返回值虽然是int ,但是它从来不会返回.即便你按下home键. 其实按下home键,应用只是进入到另外一个状态, 同时在应用内会收到特定的通知且回调特定的"回调方法". 这里不做叙述了,这是iOS应用生命周期的事情.
iOS应用的程序入口---main函数

#import <UIKit/UIKit.h>
#import "AppDelegate.h"

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

该函数只有一个return 语句,该语句返回一个UIApplicationMain函数.可以看到该函数有四个参数.

2. UIApplicationMain函数

 int UIApplicationMain(int argc, char *argv[ ], NSString * __nullable principalClassName, NSString * __nullable delegateClassName);

If nil is specified for principalClassName, the value for NSPrincipalClass from the Info.plist is used. If there is no
NSPrincipalClass key specified, the UIApplication class is used. The delegate class will be instantiated using init.

The name of the UIApplication class or subclass. If you specify nil, UIApplication is assumed.

2.1 该函数有四个参数,第1,2个和main的参数一样, 重要的是第三个,第四个参数.其类型为NSString,分别代表两个类名(ClassName),文档上对这四个参数的描述是:如果principalClassName参数为nil,那么就去应用的info.plist中查找NSPrincipalClass键所对应的值,在info.plist中如果再没有这个键值对,就使用 @"UIApplication". Xcode和网站上的文档不一致,不知为何.第四个参数delegateClassName 和第三个参数类似, 指定代理类的名字.

3. UIApplicationMain 函数做了哪些事情?

3.1 在上面说了UIApplicationMain的四个参数,既然是UIApplicationMain函数需要这传入这几个参数,那么它肯定是需要用这些参数做一些事情.首先UIApplication函数会根据传入的第三个参数principalClassName,创建一个UIApplication(或UIApplication子类)对象.
3.2 然后UIApplicationMain函数在根据第四个参数提供的代理类的类名:delegateClassName,创建一个代理对象,把该代理对象设为3.1 中创建的UIApplication或其子类对象的代理.我们可以在工程目录中看到这个代理类,默认是"AppDelegate.h"和"AppDelegate.m".就是该代理类的.
3.3 开启main run loop . 开始事件循环,响应事件.
3.4 根据info.plist文件中的设置,判断是否指定storyboard或nib文件,如果有就去加载并做相应的设置.

这里重申一下:UIApplicationMain函数做的事情是创建对象,而不是类,它还没那么智能到去自动合成一个符合具体需求的类,系统倒是能创建默认的类,那都是写死的. 这个函数所做的只是根据类名找到所属的类,去创建该类的实例. 一般情况下我们都是使用系统默认的application类.然后创建一个默认的代理对象.APPDelegate对象.如果你不指定,这个类的创建也是默认的.

UIApplication类
听名字就可以猜测到根据这个类创建的对象是应用级的,事实也是如此.它是一个iOS应用程序的象征,在一个应用中只能有一个这种对象.它是个单例对象,我们从上面的加载顺序中就知道,它是被UIApplicationMain函数创建,而且是在应用程序执行过程中创建的第一个对象,因为它是一个iOS应用的象征,一个iOS应用只能有一个这种对象. 一般我们很少直接对UIApplication对象做操作.

  • 我们不应该通过alloc来获取该对象,会报错---只能有一个UIApplication对象, 我们应该通过该类提供的一个类方法sharedApplication 来获取该对象.该类有两个重要的属性:windows , keyWindow. 还有一个代理属性后面会说到.我们可以使用该类提供的方法和属性来进行一些应用级别的操作和设置. 如联网指示器的显示与否,统一设置应用的状态栏,IconBadgeNumber 等...
 UIApplication* application = [[UIApplication alloc]init];

reason: 'There can only be one UIApplication instance.' 不该直接通过alloc的方式获取APP对象.应该使用系统提供的类方法.

下面简单介绍通过APP对象设置统一设置状态栏显示效果,其他APP对象的应用级的使用...改天再细说

//统一设置APP状态栏的显示效果
//通过sharedApplication获取该程序的UIApplication对象
UIApplication *app=[UIApplication sharedApplication];
//设置状态栏的样式
app.statusBarStyle=UIStatusBarStyleDefault;//默认黑色
//使用方法设置样式和动画
[app setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];
//设置状态栏是否隐藏
app.statusBarHidden=YES;
//设置是否隐藏和动画
[app setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade];

UIApplicationDelegate
该第四个参数了,不对!现在说的,它比第四个参数还重要. 从参数名中可以看出第四个参数是代理类的名字,既然是代理(delegate),那可定需遵循一定的协议,没错!这个协议就是UIApplicationDelegate

The UIApplicationDelegate protocol defines methods that are called by the singleton UIApplication object in response to important events in the lifetime of your app.

这个代理中的方法会在应用运行生命周期中的一些重大时刻被UIApplication对象(就是前面那个被applicationMain函数创建的对象)回调,这个不难理解,这个协议就是UIApplication对象所委托代理对象做的事情.

既然官方文档都说了,在应用程序生命周期中所发生的一些重大事件才会回调这些方法,方法有限,看看都是哪些重大事件:

//挑几个眼熟的贴上来
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //设置window
    self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.rootViewController = [[ViewController alloc]init];
    
    [self.window makeKeyAndVisible];
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

- (void)applicationWillTerminate:(UIApplication *)application {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

都是从iOS工程目录中appDelegate.m文件中Copy来的*这个文件是系统默认生成的UIApplication对象的代理类,所以已经把遵守的协议给你带上了,直接在里面填代码就OK了.不过苹果的这种做法的确是让我们写程序是少废了不少功夫,但是给初学者在刚学习的时候,造成很大迷惑.很难对整个iOS应用的运行概况有个清晰的认识.

不知不觉,十二点了.睡吧.下次接着写... 发现越写东西越多,还担心写错,尽力把自己知道的都说写出来就OK啦. Good night !

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,179评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,229评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,032评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,533评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,531评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,539评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,916评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,813评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,568评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,654评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,354评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,918评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,152评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,852评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,378评论 2 342

推荐阅读更多精彩内容