首先启动main.m文件里的 main函数
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
说明一下:
1、UIApplicationMain()方法返回值是int类型。
方法签名:
// 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.
UIKIT_EXTERN int UIApplicationMain(int argc, char *argv[], NSString * __nullable principalClassName, NSString * __nullable delegateClassName);
2、函数有4个参数
1.argc 是启动参数,不用去管.
2.argv 是启动参数,不用去管.
3.nil 第三个参数传了nil,也就是方法签名里的 NSString *__nullable principalClassName.
principal adj. 主要的;资本的 n. 首长;校长;资本;当事人
对这个参数的注释是:if nil is specified for principalClassName,the value for NSPrincipalClass from info.plist is used.
如果,这个参数传递了nil,那么就会使用info.plist文件的配置信息。
于是就立马看了下项目里的plist,没有一个配置是对类型的描述的。所以不知道这个参数是干嘛使的。
//If there is no NSPrincipalClass key specified, the UIApplication class is used
接着的注释表达的意思,如果没有在info.plist里有对应的key是 NSprincipalClass ,就会默认使用 UIApplication 类型。
所以,第三个参数用的就是UIApplication class。
4.第四个参数的签名是:NSString * __nullable delegateClassName 看起来应该是一个委托类类型对象。
传递的参数是 [AppDelegate class] AppDelegate 的类对象。
第四个参数的注释是:the delegate class will be instantiated using init;
这个委托类型将会用于实例化。
instantiated v .实例化;具体化;实体化;
AppDelegate 类名后面有个 delegate 的后缀,这个类可能是满足了某个协议。
查看这个类的定义:
定义如下:
#import
【如果看到 #import ApplicationKit/ApplicationKit.h 就说明这个项目可能是开发MAC OS的。】
@interface AppDelegate : UIResponder
@property (strong,nonatomic) UIWindow *window;
@end
说明了3个问题:
1、AppDelegate 继承了 UIResponder类型。
2、AppDelegate 内部有一个默认的UIWindow类型的属性。(UIWindow : UIView : UIResponder)
3、最重要的一点,AppDelegate 实现了 UIApplicationDelegate 协议。
接着看看 UIApplicationDelegate 里定义了哪些方法。
- (void)applicationDidFinishLaunching:(UIApplication *)application;
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(nullable NSDictionary *)launchOptions NS_AVAILABLE_IOS(6_0);
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(nullable NSDictionary *)launchOptions NS_AVAILABLE_IOS(3_0);
- (void)applicationDidBecomeActive:(UIApplication *)application;
- (void)applicationWillResignActive:(UIApplication *)application;
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
所以AppDelegate.m 文件里就实现了这些协议的方法了。
线索很零散,需要整理一下。
首先启动函数有4个参数,前2个不用管。后面接着的nil,会默认使用UIApplication类型,最后一个使用了AppDelegate类(实现了UIApplicationDelegate协议,内部还有一个默认的UIWindow属性);
这两个类型是如何分工的?
UIApplication 类是干嘛的?
AppDelegate 又是干嘛的?从协议方法来看,貌似是监控整个iOS程序声明周期的。那么UIAppliaction 又启到了什么作用呢?
答案呼之欲出了:UIApplication 表示了整个iOS程序。而AppDelegate 实现协议方法,提供UIApplication 生命周期中关键时刻的方法实现。
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
so:argc,argv who tm cares ?
nil = UIApplication 表示整个iOS程序本身
NSStringFromClass([AppDelegate class]) 实现协议方法,提供UIApplication 生命周期中关键时刻的方法实现。
ps:NSStrinFromClass([AppDelegate class]);是通过【类的class信息】,获取类名字符串的函数。所以第4个函数传递的是NSString * 类型。
证明:UIApplicationMain 函数的 第三个参数就是UIApplication,第四个参数就是AppDelegate.
这是一个没有改过main.m 启动函数的代码片段
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
//return UIApplicationMain(argc, argv, @"UIApplication", @"AppDelegate");
}
}
这是程序启动界面:
可以正常启动。
现在修改UIApplicationMain 函数代码参数为NSString * 常量。
接着再次启动启动这个程序
发现可以正常运行。于是就证明了之前的推断是正确的。
ps:什么是【类的class信息】?在iOS系统启动之后,所有的类都会以class的形式存放在代码区中。这个class的类类型包含了当前类名(className),当前类的属性列表(propertyList),方法列表(SELList),方法本身也是对象,以单个元素的形式存放在SELList列表里。