標籤:
程式啟動開始到view顯示:
程式啟動首先會執行main函數 - > UIApplicationMain函數:
- 程式啟動 (載入架構,info檔案,資源等)
- 執行Main函數
- 初始化UIApplication單例對象
- 初始化AppDelegate對象,並設為UIApplication對象的代理
- 然後調用UIApplication的didFinishLaunchingWithOptions方法建立UIWindow對象,設定rootViewController根控制器等
- 然後建立一個主事件迴圈,其中包含UIApplication的Runloop來開始處理事件。
執行main函數
main函數作為程式的主入口,程式啟動就自動執行main函數(main函數是一個死迴圈,保證了程式不會自動關閉)
1 /**2 * 1.1程式執行首先執行main函數3 */4 int main(int argc, char argv[]) {5 @autoreleasepool {6 return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));7 }8 }
初始化UIApplication單例對象
初始化AppDelegate對象,並設為UIApplication對象的代理
建立UIApplication單例對象,並且設定UIApplication的Delegate對象(進入main函數後,首先就執行UIApplicationMain函數)
所以啟動程式就會建立application單例對象,並且設定了AppDelegate為application對象的代理
看看內部的定義:
// argc、argv:直接傳遞給UIApplicationMain進行相關處理即可// principalClassName:指定應用程式類名(app的象徵),該類必須是UIApplication(或子類)。如果為nil,則用UIApplication類作為預設值// delegateClassName:指定應用程式的代理類,該類必須遵守UIApplicationDelegate協議int UIApplicationMain(int argc, char argv[], NSString principalClassName, NSString delegateClassName);
調用UIApplication的didFinishLaunchingWithOptions方法建立UIWindow單例對象
程式啟動完成後 , 接著會建立應用程式的Main Runloop(事件迴圈),進行事件的處理(首先會在程式完畢後調用delegate對象的application:didFinishLaunchingWithOptions:方法) Runloop的理解,可參考文章 : 轉載自【楚天舒iOS程式與運行Runloop】 application的代理方法淺析
1 // 當應用程式啟動完畢的時候就會調用(系統自動調用) 2 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 3 { 4 //建立UIWindow,設定rootViewControlle等的操作都是在這裡完成 5 6 // 1 . 建立UIwindow對象 7 self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 8 9 // 2 . 建立和設定UIWindow的rootViewController(根控制器)10 CwlMainViewController *mainViewController = [CwlMainViewController alloc] init];11 self.window.rootViewController = mainViewController;12 13 // 3 . 顯示視窗14 [self.window makeKeyAndVisable]; 15 16 return YES; 17 } 18 // 即將失去活動狀態的時候調用(失去焦點, 不可互動) 19 - (void)applicationWillResignActive:(UIApplication *)application 20 { 21 } 22 23 // 重新擷取焦點(能夠和使用者互動) 24 - (void)applicationDidBecomeActive:(UIApplication *)application 25 { 26 27 } 28 29 // 應用程式進入背景時候調用 30 - (void)applicationDidEnterBackground:(UIApplication *)application 31 { 32 // 一般在該方法中儲存應用程式的資料, 以及狀態 33 } 34 35 // 應用程式即將進入前台的時候調用 36 - (void)applicationWillEnterForeground:(UIApplication *)application 37 { 38 // 一般在該方法中恢複應用程式的資料,以及狀態39 } 40 41 // 應用程式即將被銷毀的時候會調用該方法 42 - (void)applicationWillTerminate:(UIApplication *)application 43 { 44 // 注意:如果應用程式處於掛起狀態的時候無法調用該方法45 // 提醒是否關閉,儲存重要訊息等46 } 47 48 // 應用程式接收到記憶體警告的時候就會調用 49 - (void)applicationDidReceiveMemoryWarning:(UIApplication *)application 50 { 51 // 這裡是監控全域的記憶體警告方法,所有記憶體警告首先會由這裡接收到,再傳遞到各個控制器進行處理,一般在該方法中釋放掉不需要的記憶體 52 }
控制器的多種建立方式
1. 通過storyboard直接建立
2. 直接建立
CwlViewController *cwl = [[CwlViewController alloc] init];
3. 通過xib檔案建立
CwlViewController *cwl = [[CwlViewController alloc] initWithNibName:@"CwlViewController" bundle:nil]];
控制器的View的多種建立方式
建立完控制器之後,會建立控制器的view,view的建立有多種情況,看:
需要注意的地方
1. 控制器的loadView方法優先順序是最高的
2. 因為在官方文檔的圖片中,已經忽略xib的情況,如果storyboard沒被設定,就先判斷xib檔案,詳細效果是這樣。
【學習總結】IOS程式運行過程 、UIWindow 、controller 、 UIView 建立過程的總結