iOS開發之UIApplication,iosuiapplication
UIApplication的核心作用是提供了iOS程式運行期間的控制和協作工作。
iPhone應用程式是由主函數main啟動,它負責調用UIApplicationMain函數,該函數的形式如下所示:
int UIApplicationMain (
int argc,
char *argv[],
NSString *principalClassName,
NSString *delegateClassName
);
argc、argv:直接傳遞給UIApplicationMain進行相關處理即可
principalClassName:指定應用程式類名(app的象徵),該類必須是UIApplication(或子類)。如果為nil,則用UIApplication類作為預設值
delegateClassName:指定應用程式的代理類,該類必須遵守UIApplicationDelegate協議
UIApplicationMain函數會根據principalClassName建立UIApplication對象,根據delegateClassName建立一個delegate對象,並將該delegate對象賦值給UIApplication對象中的delegate屬性
那麼UIApplicationMain函數到底做了哪些事情呢?這個函數主要負責三件 事情:
1)從給定的類名初始化應用程式物件,也就是初始化UIApplication或者子類對象的一個執行個體,如果你在這裡給定的是nil,那麼系統會預設UIApplication類,也就主要是這個類來控制以及協調應用程式的運行。在後續的工作中,你可以用靜態方法sharedApplication 來擷取應用程式的控制代碼。
2)從給定的應用程式委託類,初始化一個應用程式委託。並把該委託設定為應用程式的委託,這裡就有如果傳入參數為nil,會調用函數訪問 Info.plist檔案來尋找主nib檔案,擷取應用程式委託。
3)啟動主事件迴圈,並開始接收事件。
上面是UIApplicationMain函數的工作,接下來一個問題是應用程式視圖的顯示、訊息的控制怎麼辦?下面就是UIApplication(或者子類)對象的職責,這個對象主要做下面幾件事:
1)負責處理到來的使用者事件,並分發事件訊息到應該處理該訊息的目標對象(sender, action)。
2)管理以及控制視圖,包括呈現、控制行為、當前顯示視圖等。
3)該對象有一個應用程式委派物件,當一些生命週期內重要事件(可以包括系統事件或者生命週期控制事件)發生時,代理程式更新該對象。例如,應用程式啟 動、記憶體不夠了或者應用程式結束等,讓這些事件發生時,應用程式委託去響應。
通過上面的分析,可以知道UIApplication對開發人員來說,是一個黑箱,因為所有的操作,都可以由它的委託來幫我們完成,它只需要在 後面維護一些不可更改的東西,如事件訊息分發和傳遞、給委託發送事件處理請求等等,如,應用程式載入處理完畢,它會發送訊息給委託,然後委託可以在 applicationDidFinishLanching委託函數中去實現開發人員想要的動作。利用XCode在建立應用程式時,會預設實現一個應用程式 委託類。而對於載入的視圖,則有視圖相關的委託類來處理視圖載入過程的生命事件。下面說明委託主要可以辦哪些事情:
控制應用程式的行為
- (void)applicationDidFinishLaunching:(UIApplication *)application
應用程式啟動完畢。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
當由於其它方法開啟應用程式(如URL指定或者串連),通知委託啟動完畢
- (void)applicationWillTerminate:(UIApplication *)application
通知委託,應用程式將在關閉 退出,請做一些清理工作。
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
通知委託,應用程式收到了為來自系統的記憶體不足警告。
- (void)applicationSignificantTimeChange:(UIApplication *)application
通知委託系統時間發生改變(主要是時間屬性, 而不是具體時間)
開啟URL
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
開啟指定的URL
[[UIApplicationsharedApplication] openURL:[NSURLURLWithString:@"mailto://admin@hzlzh.com"]];
// 調用 電話phone
[[UIApplication sharedApplication] openURL:[NSURLURLWithString:@"tel://8008808888"]];
// 調用 SMS
[[UIApplicationsharedApplication] openURL:[NSURL URLWithString:@"sms://800888"]];
// 調用內建 瀏覽器 safari
[[UIApplicationsharedApplication] openURL:[NSURLURLWithString:@"http://www.hzlzh.com"]];
// 調用 Remote
[[UIApplicationsharedApplication] openURL:[NSURL URLWithString:@"remote://fff"]];
調用phone可以傳遞號碼,調用SMS只能設定號碼,不能初始化SMS內容。
控制狀態列方位變化
– application:willChangeStatusBarOrientation:duration:
裝置方向將要發生改變
– application:didChangeStatusBarOrientation:
活動狀態改變
- (void)applicationWillResignActive:(UIApplication *)application
通知委託應用程式將進入非使用中,在此期間,應用程式不接收訊息或事件。-(void)applicationDidBecomeActive:(UIApplication *)application
通知委託應用程式進入活動狀態,請恢複資料
可以看到UIApplication的標頭檔實現
@interface UIApplication :UIResponder {
@package
id _delegate ; //這就是應用程式委託。
NSTimer .......
}
因此,在UIApplication中處理的系統事件時,只需轉到_delegate這個類去處理, 這個類對象就是應用程式委派物件。我們可以從應用程式的單例類對象中得到應用程式委託的對象
UIApplicationDelegate* myDelegate = [[UIApplication sharedApplication] delegate];
UIApplication 接收到所有的系統事件和生命週期事件時,都會把事件傳遞給UIApplicationDelegate進行處理,對於使用者輸入事件,則傳遞給相應的目標對象去處理。比如我們在應用程式被來電等訊息後,可以調用應用程式委託類的 applicationWillResignActive()方法,這個方法在使用者鎖住螢幕時,也會調用,與之相適應的是應用程式重新被使用者開啟時的委託 方法。另外常用的就是記憶體不足的系統警告,此時會調用應用程式委託類的applicationDidReceiveMemoryWarning()方法, 然後我們就可以試著釋放一些記憶體了。