iOS學習之應用程式的啟動原理,ios應用程式原理
最近看視頻瞭解了一下應用程式的啟動原理,這裡就做一個部落格和大家分享一下,相互討論,如果有什麼補充或不同的意見可以提出來!
1、程式入口
眾所周知,一個應用程式的入口一般是一個 main 函數,iOS也不例外,在工程的 Supporting Files 檔案夾中你可以找到main.m,他就是程式的入口。
代碼:
int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil,NSStringFromClass([AppDelegate class])); }}
2、UIApplicationMain函數參數解析
UIApplicationMain 函數的聲明:
// 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.int UIApplicationMain(int argc, char *argv[], NSString * __nullable principalClassName, NSString * __nullable delegateClassName);
第一個參數 argc 和 第二個參數 argv 為C語言的值,在這裡可以不做考慮。
第三個參數 principalClassName:主程式類名,由英文注釋可知,當值為 nil 時,預設使用的就是 UIApplication
第四個參數:delegateClassName:代理類名,在 iOS 中預設就是隨工程一起建立出來的AppDelegate。
第四個參數的類型是一個字串,但是在主函數卻是 NSStringFromClass([AppDelegate class]) 。NSStringFromClass() 函數是將一個類名轉為字串的一種特殊轉換函式,[AppDelegate class] 則是反射得到AppDelegate 對象的類名。
和 NSStringFromClass() 函數類似的一系列函式宣告:
FOUNDATION_EXPORTNSString *NSStringFromSelector(SEL aSelector); // 函數名轉字串FOUNDATION_EXPORT SEL NSSelectorFromString(NSString *aSelectorName); // 字串轉函數名FOUNDATION_EXPORT NSString *NSStringFromClass(Class aClass); // 類名轉字串FOUNDATION_EXPORT Class __nullable NSClassFromString(NSString *aClassName); // 字串轉類名FOUNDATION_EXPORT NSString *NSStringFromProtocol(Protocol *proto) NS_AVAILABLE(10_5, 2_0); // 協議名轉字串FOUNDATION_EXPORT Protocol * __nullable NSProtocolFromString(NSString *namestr) NS_AVAILABLE(10_5, 2_0); // 字串轉協議名
3、UIApplicationMain底層實現
(1)根據 principalClassName 提供類名建立 UIApplication 對象
(2)建立 UIApplicationDelegate 對象,並且成為 UIApplication 對象代理,app.delete = delegate
(3)開啟一個主運行迴圈,處理事件,可以保持程式一直運行。
(4)載入 info.plist,並且判斷 Main Interface 有木有指定 main.storyboard,如果指定,就會去載入
(5)如果有指定,載入 main.stroyboard 做的事情
建立視窗,也就會說執行 AppDelegate 中的代理方法
載入 main.storyboard, 並且載入 main.storyboard 指定的控制器
把新建立的控制器作為視窗的跟控制器,讓視窗顯示出來
(6)如果沒有指定,就在 AppDelegate 的代理方法 - (BOOL)application: didFinishLaunchingWithOptions:中建立一個UIWindow 對象作為主視窗
代碼:
// 程式啟動完成的時候- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. // 1.建立視窗,注意視窗必須要有尺寸,尺寸跟螢幕一樣大的尺寸,視窗不要被釋放 self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; self.window.backgroundColor = [UIColor redColor]; // 2.建立視窗的根控制器 UIViewController *vc = [[UIViewController alloc] init]; vc.view.backgroundColor = [UIColor yellowColor]; [vc.view addSubview:[UIButton buttonWithType:UIButtonTypeContactAdd]]; // 如果設定視窗的跟控制器,預設就會把控制器的view添加到視窗上 // 設定視窗的跟控制器,預設就有旋轉功能 self.window.rootViewController = vc; // 3.顯示視窗 [self.window makeKeyAndVisible]; return YES;}
圖解: 官方協助文檔圖解: