標籤:
-
- iOS程式啟動流程
- 完整啟動流程
- UIApplicationMain方法
- UIApplication
- AppDelegate代理生命週期回調
- UIWindow
- UIViewController控制器
- 控制器View的載入
- iOS工程常見檔案
- xxx-Infoplist檔案
- InfoPliststrings
- xxx-Prefixpch
- Defaultpng
- Iconpng
iOS程式啟動流程
1. 完整啟動流程
- 點擊程式表徵圖
- 執行main函數
- 執行UIApplicationMain函數
- 建立UIApplication對象、UIApplication的delegate對象
- 開啟事件迴圈監聽系統
- 程式載入完畢後調用delegate對象的
application:didFinishLaunchingWithOptions:方法
- 建立視窗對象
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
- 建立控制器對象
self.viewController = [[MJViewController alloc] initWithNibName:@"MJViewController" bundle:nil];
- 設定視窗的根控制器
self.window.rootViewController = self.viewController;
- 讓視窗成為主視窗、並且可見
[self.window makeKeyAndVisible];
2. UIApplicationMain方法
??在main.m的main函數中執行了UIApplicationMain這個方法,這是ios程式的進入點
int UIApplicationMain(int argc, char *argv[], NSString *principalClassName, NSString *delegateClassName)
argc、argv:ISO C標準main函數的參數,直接傳遞給UIApplicationMain進行相關處理即可;
principalClassName:指定應用程式類,該類必須是UIApplication(或子類)。
delegateClassName:指定應用程式類的代理類,該類必須遵守UIApplicationDelegate協議;
此函數會根據principalClassName建立UIApplication對象,根據delegateClassName建立一個delegate對象,並將該delegate對象賦值給UIApplication對象中的delegate屬性;UIApplication對象會依次給delegate對象發送不同的訊息,接著會建立應用程式的main runloop(事件迴圈),進行事件的處理(首先會調用delegate對象的 application:didFinishLaunchingWithOptions:),程式正常退出時這個函數才返回。如果進程要被系統強制殺死,一般這個函數還沒來得及返回進程就終止了。
3. UIApplication
UIApplication是應用程式的核心,每一個程式在運行期必須有UIApplication(或子類)的一個執行個體(有且僅有一個),通過[UIApplication sharedApplication]可以得到這個單例執行個體的指標。
UIApplication協助管理應用程式的生命週期,而它通過delegate來履行這個任務。
UIApplication可以接收事件,把所有使用者事件都放入隊列,逐個處理,它會發送當前事件給一個合適的目標控制項進行處理。它還將部分事件轉給delegate對象來處理,delegate可處理的事件包括:應用程式的生命週期事件(如程式啟動和關閉)、系統事件(如來電)
- (IBAction)click { UIApplication *app = [UIApplication sharedApplication]; //影藏顯示狀態列 app.statusBarHidden = No; // 設定表徵圖右上方的數字 app.applicationIconBadgeNumber = 0; // 設定是否需要顯示網路連接狀態 app.networkActivityIndicatorVisible = YES; // 打電話\發簡訊\發郵件\開啟safari瀏覽器 NSURL *url = [NSURL URLWithString:@"tel://10086"]; NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"]; [app openURL:url];}
4. AppDelegate代理(生命週期回調)
??UIApplicationMain方法根據第四個參數delegateClassName產生應用程式類的代理(該類必須遵守UIApplicationDelegate協議),然後設定給UIApplication。應用程式生命週期發生變化就會調用AppDelegate代理中的方法。
@implementation MJAppDelegate#pragma mark 在應用程式啟動完畢後調用(只會調用一次,第一次開啟程式的時候才會調用)- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{}#pragma mark 在app進入前台的時候調用- (void)applicationWillEnterForeground:(UIApplication *)application{}#pragma mark 當app獲得焦點的時候調用(已啟用)- (void)applicationDidBecomeActive:(UIApplication *)application{}#pragma mark 當app失去焦點的時候調用(未啟用)- (void)applicationWillResignActive:(UIApplication *)application{}#pragma mark 在app進入背景時候調用- (void)applicationDidEnterBackground:(UIApplication *)application{}#pragma mark 當app被關閉的時候會調用(前提條件:app在後台啟動並執行時候)- (void)applicationWillTerminate:(UIApplication *)application{}@end
5. UIWindow
??UIWindow是一種特殊的UIView,通常在一個app中只會有一個UIWindow,但可以手動建立多個UIWindow。
UIWindow的主要作用:
①、提供一個地區來顯示視圖
②、將事件分發給視圖
③、與UIViewController協同工作,方便完成裝置方向旋轉的支援
添加UIView到UIWindow中兩種常見方式:
①、addSubview:直接將UIView添加到UIWindow中,程式負責維護UIView的生命週期以及重新整理,但並不會理會UIView對應的UIViewController
②、rootViewController:自動將UIViewController對應的UIView添加到UIWindow中,同時負責維護UIViewController和UIView的生命週期
常用方法
makeKeyWindow:讓當前UIWindow變成keyWindow
makeKeyAndVisible:讓當前UIWindow變成keyWindow,並顯示出來
6. UIViewController控制器
??UIViewController屬於MVC模型中的C(Controller),說的更具體點它是一個視圖控制器,管理著一個視圖(UIView)。
??一個UIViewController應該只管理一個view hierarchy,通常來說一個完整的view hierarchy指的是佔滿整一個螢幕。而很多app滿屏中會有各個地區分管不同的功能,一些開發人員喜歡直接建立一個UIViewController和一套相應的view來完成所要的功能,這樣做完全不符合Apple提供的設計規範。
UIViewController生命週期方法:
①、當view載入後調用viewDidLoad,這裡可以進行一些資料的請求或載入,用來更新介面
②、當view將要被加入view hierarchy時調用viewWillAppear,完成加入時調用viewDidAppear
③、當view將要從view hierarchy中移除時調用viewWillDisappear,完成移除時調用viewDidDisappear
④、當記憶體緊張時, 調用didReceiveMemoryWarning,其預設實現是如果當前UIViewController的view的superview是nil,則將view釋放且調用viewDidUnload, viewDidUnload中你可以進行後繼的記憶體清理工作(主要是介面元素的釋放,當再次載入的時候需要重建)
(這裡的view是指UIViewController內部的view屬性)
7. 控制器View的載入
??應用程式啟動後,會調用代理的application:didFinishLaunchingWithOptions:方法,在這個方法中會完成控制器和View的載入。
??控制器MJViewController的view是消極式載入的,用到view時,就會調用控制器的loadView方法載入view,loadView載入view的預設過程(UIViewController的預設實現):
1> 如果nibName有值,就會載入對應的xib檔案來建立view2> 如果nibName沒有值 1) 優先載入MJView.xib檔案來建立view 2) 載入MJViewController.xib檔案來建立view 3) 如果沒有找到上面所述的xib檔案,就會用代碼建立一個黑色的view
@implementation MJAppDelegate- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // 建立控制器(控制器的view是延時載入:用到時再載入) self.viewController = [[MJViewController alloc] initWithNibName:@"MJViewController" bundle:nil]; // 如果執行下面設定view背景的方法,就會調用loadView載入view //self.viewController.view.backgroundColor = [UIColor blueColor]; // 設定根控制器(沒有用到根控制器的view) self.window.rootViewController = self.viewController; // 設定視窗可見(此時會載入view) [self.window makeKeyAndVisible]; return YES;}
@implementation MJViewController#pragma mark 如果不重寫loadView,UIViewController預設實現- (void)loadView{ // 不應該調用super的loadView // [super loadView]; //NSLog(@"---loadView"); // 死迴圈 //self.view = [[UIScrollView alloc] initWithFrame:self.view.frame]; // 返回最適合控制器view的frame CGRect frame = [UIScreen mainScreen].applicationFrame; //NSLog(@"%@", NSStringFromCGRect(frame)); self.view = [[UIScrollView alloc] initWithFrame:frame]; self.view.backgroundColor = [UIColor yellowColor];}*/#pragma mark view 載入完畢後調用- (void)viewDidLoad{ [super viewDidLoad]; // 初始化子控制項}@end
iOS工程常見檔案
1. xxx-Info.plist檔案
??項目中最主要的檔案,描述了軟體名稱、軟體版本、唯一標識等,修改Summery相當於修改此檔案。相當於Android的資訊清單檔AndroidManifest.xml
??Bundle version -版本號碼(每次往App Store上發布一個新版本時,需要增加這個版本號碼)
??Bundle display name - 軟體名稱(限制在10-12個字元,如果超出,將被顯示縮寫名稱)
??Localiztion native development region-本地化相關
??Icon file-app表徵圖名稱,一般為Icon.png
??Main nib file base name-主nib檔案的名稱
??Bundle identifier-項目的唯一標識,部署到真機時用到
??…
注意: 在Xcode3的時候檔案名稱叫做:Info.plist,所以我們在建立.plist檔案時不要取名為Info或者info.plist
2. InfoPlist.strings
??國際化相關配置
3. xxx-Prefix.pch
??一般來說,可以將項目中經常用到的一些標頭檔放在這裡來import,整個項目都可以訪問這個檔案的內容,這樣既節省了手動添加import的時間,也有助於加速編譯。在這裡定義的宏,整個項目都可以訪問。
??樣本:在pch檔案中添加下列預先處理指令,然後在項目中使用Log(…)來輸出日誌資訊,就可以在發布應用的時候,一次性將NSLog語句移除(在偵錯模式下,才有定義DEBUG)
/* 如果軟體處於調試狀態,系統會預設定義一個叫做DEBUG的宏; 如果軟體處於發布打包狀態,系統就不會定義DEBUG這個宏 */#ifdef DEBUG// 調試狀態:將MJLog替換成NSLog#define MJLog(...) NSLog(__VA_ARGS__)#else// 發布狀態:將MJLog替換成空#define MJLog(...) #endif
4. Default.png
??應用程式在啟動過程中會全螢幕顯示叫做Default.png的圖片,不同螢幕解析度會載入不同的圖片,如果沒找到會使用最接近的那張(系統自動識別)
Default.png 320x480
[email protected] 640x960
[email protected] 640x1136
5. Icon.png
??應用程式圖示
??蘋果官方文檔搜尋”app icon” –>App Icons on iPad and iphone
??
iOS應用程式工程檔案以及啟動流程