iOS程序啓動原理
iOS程序啓動原理
技術博客http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/luohanchenyilong
iOS應用程序運行流程
UIApplicationMain
★ 在main.m的main函數中執行了UIApplicationMain這個方法,這 是ios程序的入口點
★intUIApplicationMain(intargc,char*argv[], NSString *principalClassName, NSString *delegateClassName)
★ argc、argv:ISO C標準main函數的參數,直接傳遞 給UIApplicationMain進行相關處理便可
★ principalClassName:指定應用程序類,該類必須 是UIApplication(或子類)。若是爲nil,則用UIApplication類 做爲默認值
★ delegateClassName:指定應用程序類的代理類,該類必須遵 守UIApplicationDelegate協議
UIApplicationMain
★ 此函數會根據principalClassName建立UIApplication 對象,根據delegateClassName建立一個delegate對象 ,並將該delegate對象賦值給UIApplication對象中 的delegate屬性
★ UIApplication對象會依次給delegate對象發送不一樣的 消息,接着會創建應用程序的main runloop(事件循環) ,進行事件的處理(首先會調用delegate對象的
application:didFinishLaunchingWithOptions:)
★ 程序正常退出時這個函數才返回。若是進程要被系統強制 殺死,通常這個函數還沒來得及返回進程就終止了
★ 若是設置了主xib文件(在Info.plist中指定 ,key是NSMainNibFile),就會在主xib文件中 尋找UIApplication和鏈接它的delegate。因 此在主xib文件中,File’s Owner必須 爲UIApplication(或子類),而且創建一個遵 守UIApplicationDelegate的delegate對象, 創建UIApplication和delegate對象的關聯關係
四大對象關係圖
iOS中的mvc
UIApplication
★ UIApplication是應用程序的核心,每個程序在運行期必須 有UIApplication(或子類)的一個實例(有且僅有一個),通 過[UIApplication sharedApplication]能夠獲得這個單例實例 的指針
★ UIApplication幫助管理應用程序的生命週期,而它經過delegate 來履行這個任務
★ UIApplication能夠接收事件,把全部用戶事件都放入隊列,逐個 處理,它會發送當前事件給一個合適的目標控件進行處理。它還將部分 事件轉給delegate對象來處理,delegate可處理的事件包括:應用程 序的生命週期事件(如程序啓動和關閉)、系統事件(如來電)
UIApplication
★ [UIApplication sharedApplication].windows: 在本應用中打開的UIWindow列表,這樣就能夠接觸應用
中的任何一個UIView對象
★ [UIApplication sharedApplication].keyWindow: 用來接收鍵盤以及非觸摸類的消息事件的UIWindow,而
且程序中每一個時刻只能有一個UIWindow是keyWindow。 若是某個UIWindow內部的文本框不能輸入文字,多是 由於這個UIWindow不是keyWindow
下面是這個類的一些功能:
1.設置icon上的數字圖標
//設置主界面icon上的數字圖標,在2.0中引進, 缺省爲0
[UIApplicationsharedApplication].applicationIconBadgeNumber = 4;
2.設置搖動手勢的時候,是否支持redo,undo操做
//搖動手勢,是否支持redo undo操做。
//3.0之後引進,缺省YES
[UIApplicationsharedApplication].applicationSupportsShakeToEdit =YES;
3.判斷程序運行狀態
//判斷程序運行狀態,在2.0之後引入
/*
UIApplicationStateActive,
UIApplicationStateInactive,
UIApplicationStateBackground
*/
if([UIApplicationsharedApplication].applicationState ==UIApplicationStateInactive){
NSLog(@"程序在運行狀態");
}
4.阻止屏幕變暗進入休眠狀態
//阻止屏幕變暗,慎重使用,缺省爲no 2.0
[UIApplicationsharedApplication].idleTimerDisabled =YES;
(慎重使用本功能,由於很是耗電)
5.顯示聯網狀態
//顯示聯網標記 2.0
[UIApplicationsharedApplication].networkActivityIndicatorVisible =YES;
6.在map上顯示一個地址
NSString* addressText =@"1 Infinite Loop, Cupertino, CA 95014";
// URL encode the spaces
addressText= [addressTextstringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSString* urlText = [NSStringstringWithFormat:@"http://maps.google.com/maps?q=%@", addressText];
[[UIApplicationsharedApplication]openURL:[NSURLURLWithString:urlText]];
7.發送電子郵件
NSString *recipients =@"mailto:first@example.com?cc=second@example.com,third@example.com&subject=Hello from California!";
NSString *body =@"&body=It is raining in sunny California!";
NSString *email = [NSStringstringWithFormat:@"%@%@", recipients, body];
email = [emailstringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[[UIApplicationsharedApplication]openURL:[NSURLURLWithString:email]];
8.打電話到一個號碼
// Call Google 411
[[UIApplicationsharedApplication]openURL:[NSURLURLWithString:@"tel://8004664411"]];
9.發送短信
// Text to Google SMS
[[UIApplicationsharedApplication]openURL:[NSURLURLWithString:@"sms://466453"]];
10.打開一個網址
// Lanuch any iPhone developers favsite
[[UIApplicationsharedApplication]openURL:[NSURLURLWithString:@"http://itunesconnect.apple.com"]];
UIApplicationDelegate
★ 在開發過程當中,UIApplication是一個很是重要的全局對象。但在實 際編程中咱們並不直接和UIApplication對象打交道,而是和其代理 打交道,它的代理必須遵照UIApplicationDelegate協議,代理 供了相關的生命週期方法來處理應用程序的系統事件
> ★ ios設備的內存極其優先,若是爲app分配了太多內存,操做系統會終 止app的運行,在UIApplication接收到這個事件後它會調用代理 的applicationDidReceiveMemoryWarning方法,代理在這個方 法內能夠進行釋放內存的操做以防止操做系統強制終止應用程序的運行
>
> UIApplicationDelegat
> ★ ios並非多任務的操做系統,因此app很容易受到打擾。好比一個來 電可能致使app失去焦點,若是這個時候接聽了電話,那麼app會自動 終止運行
> ★ 還有不少其它相似的事件會致使app失去焦點
> ★ app失去焦點前會調用代理的applicationWillResignActive
> ★ app再次獲取焦點時會調用代理的applicationDidBecomeActive
> ★ 在運行app時鎖屏會調用代理的applicationWillResignActive
> ★ 當屏幕被解鎖時,會調用代理的applicationDidBecomeActive
> UIApplicationDelegate生命週期方法說明
> 1、- (void)applicationWillResignActive:(UIApplication *)application{
> / /從主動到非活動狀態的應用程序時發送。這可致使產生某些類型的臨時中斷(如傳入電話呼叫或SMS消息) ,或者當用戶退出應用程序,它開始過渡到的背景狀態。
> / /使用此方法暫停正在進行的任務,禁用定時器,踩下油門,OpenGL ES的幀速率。遊戲應該使用這種方法來暫停遊戲。
> }
> 2、- (void)applicationDidBecomeActive:(UIApplication *)applicatio
> 說明:當應用程序入活動狀態執行,這個恰好跟上面那個方法相反
> 3、- (void)applicationDidEnterBackground:(UIApplication *)application{
> 說明:當程序被推送到後臺的時候調用。因此要設置後臺繼續運行,則在這個函數裏面設置便可
> / /使用這個方法來釋放共享資源,保存用戶數據,廢止定時器,並存儲足夠的應用程序狀態信息的狀況下被終止後,將應用程序恢復到目前的狀態。
> / /若是你的應用程序支持後臺運行,這種方法被調用,而不是applicationWillTerminate :當用戶退出。
> }
> 4、- (void)applicationWillEnterForeground:(UIApplication *)applicatio
> 說明:當程序從後臺將要從新回到前臺時候調用,這個恰好跟上面的那個方法相反。
> 5、- (void)applicationWillTerminate:(UIApplication *)applicatio
> //不支持多任務的時候調用
>
> 說明:當程序將要退出是被調用,一般是用來保存數據和一些退出前的清理工做。這個須要要設置UIApplicationExitsOnSuspend的鍵值(自動設置)。
> 6、- (void)applicationDidReceiveMemoryWarning:(UIApplication *)applicatio
> 說明:iPhone設備只有有限的內存,若是爲應用程序分配了太多內存操做系統會終止應用程序的運行,在終止前會執行這個方法,一般能夠在這裏進行內存清理工做防止程序被終止
> 7、- (void)applicationSignificantTimeChange:(UIApplication*)applicatio
> 說明:當系統時間發生改變時執行
> 8、- (void)applicationDidFinishLaunching:(UIApplication*)applicatio
> 說明:當程序載入後執行
> 9、- (void)application:(UIApplication)application willChangeStatusBarFrame:(CGRect)newStatusBarFram
> 說明:當StatusBar框將要變化時執行
> 10、- (void)application:(UIApplication*)application willChangeStatusBarOrientation
> (UIInterfaceOrientation)newStatusBarOrientatio
> duration:(NSTimeInterval)duratio
> 說明:當StatusBar框方向將要變化時執行
> 11、- (BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)ur
> 說明:當經過url執行
> 12、- (void)application:(UIApplication*)application didChangeStatusBarOrientation:(UIInterfaceOrientation)oldStatusBarOrientatio
> 說明:當StatusBar框方向變化完成後執行
> 13、- (void)application:(UIApplication*)application didChangeSetStatusBarFrame:(CGRect)oldStatusBarFram
> 說明:當StatusBar框變化完成後執行
>
> UIWindow
> ★ UIWindow是一種特殊的UIView,一般在一個app中只會有一 個UIWindow,但能夠手動建立多個UIWindow
> ★ UIWindow的主要做用:
> 1 提供一個區域來顯示視
> 2 將事件分發給視
> 3 與UIViewController協同工做,方便完成設備方向旋轉的支持
>
> UIWindow
>
> 1 addSubview:直接將UIView添加到UIWindow中,程序負責維 護UIView的生命週期以及刷新,但並不會理會UIView對應 的UIViewController
> 2 rootViewController:自動將UIViewController對應的UIView 添加到UIWindow中,同時負責維護UIViewController和UIView的 生命週期
> ★ 經常使用方
> 1 makeKeyWindow:讓當前UIWindow變成keyWindo
> 2 makeKeyAndVisible:讓當前UIWindow變成keyWindow,並顯示出來
>
> UIViewControlle
> ★ UIViewController屬於MVC模型中的C(Controller),說的更具體 點它是一個視圖控制器,管理着一個視圖(UIView)
> ★ 一個UIViewController應該只管理一個view hierarchy,一般 來講一個完整的view hierarchy指的是佔滿整一個屏幕。而不少ap p滿屏中會有各個區域分管不一樣的功能,一些開發者喜歡直接新建一 個UIViewController和一套相應的view來完成所要的功能,這樣 作徹底不符合Apple供的設計規範UIViewController的view
r> ★ 當view加載後調用viewDidLoad,這裏能夠進行一些數據的請求或加載,用來更新界面★當view將要被加入view hierarchy時調用viewWillAppear,完成 加入時調用viewDidAppear ★當view將要從view hierarchy中移除時調用viewWillDisappear ,完成移除時調用viewDidDisappear ★ 當內存緊張時, 調用didReceiveMemoryWarning,其默認實現是如 果當前UIViewController的view的superview是nil,則將view釋 放且調用viewDidUnload, viewDidUnload中你能夠進行後繼的內 存清理工做(主要是界面元素的釋放,當再次加載的時候須要重建) (這裏的view是指UIViewController內部的view屬性) 工程名-Info.plist
r> #define Log(...) NSLog(__VA_ARGS_
r> #el
r> #define Log(...) /*
r> #end
r> r>
r> excepti
r> ‘NSInvalidUnarchiveOperationException
r> reason: ‘Could not instantiate cla
r> named NSLayoutConstrain
r> ★ 具體場景:Xcode 4.5 選擇iPhone/iPad 5.0/5.1 Simulator(模擬器)★ 解決辦法:須要關閉storyboard或xib界面文 件的Use Autolayout 選項,這是由於AutoLayout特性是iOS 6新增長的,在以前的 5.0/5.1 Simulator模擬器中不支持nib文件
r> 在Summary的Main Interface中
r> UIView★ UIView是iOS中界面元素的基礎,全部的界面元素都繼承它,能夠說 在iPhone中你能看到的、摸到的,都是UIView★ UIView的基本功
r> 1 繪圖和動畫(用CALayer和CAAnimation實現
r> 2 事件處理(繼承了UIRsponde
r> ★ 一個UIView能夠包含和管理若干個子視圖,決定着子視圖的位置和大小UIView經常使用屬性
視圖的中點在父視圖座標系中的
r> ★ UIView*superview父
r> ★ NSArray*subviews全部的子
r> ★ UIWindow *window 當前視圖所在的
r> ★ BOOLuserInteractionEnabledYES表明接收觸摸事件 • 在父視圖座標系中,父視圖的左上角爲座標原點(0,
r> • 在本視圖座標系中,本視圖的左上角爲座標原點(0, 0)UIKit座標系
r> (0,0)View1是View2的父視圖 View2.frame = {x=70,y=50,width=60,height=40} View2.bounds = {x=0,y=0,width=60,height=40} View2.center = (x=100, y=70)• UIKit框架中的座標系都如左圖所示,視圖的 左上角爲原點(0,0),x軸向右正向延伸,y 軸向下正向延伸• View3中frame的x,y值
r> 1 若是綠色視圖是View3的父視圖,那麼View3的x,y爲紅色箭頭的
r> 2 若是View1是View3的父視圖,那麼View3的x,y爲藍色箭頭的寬度UIView經常使用方法和屬性★ -(void)removeFromSuperview從父視圖中移除(當前視圖的計數器會-1)★ -(void)addSubview:(UIView*)view添加一個子視圖(新添加的子視圖在父視圖的最上面,子視圖的 計數器會+1)★ -(UIView*)viewWithTag:(NSInteger)tag 根據tag找到對應的子視圖iOS關閉鍵盤的方法r> ★ 調用UIView的endEditing方法,例如[self.viewendEditing:YES]; 成功關閉鍵盤的條件:self.view或者其子視圖是第一響應者iOS關閉鍵盤的方法2
r> [[self findFirstResponder:self.view]resignFirstResponder]; - (UIView*)findFirstResponder:(UIView*)view {for ( UIView *childView in view.subviews
r> { // 遍歷子視
r> if ( [childViewrespondsToSelector:@selector(isFirstResponder)] && [childView isFirstResponder] ) {return childView; // 若是childView是第一響應
r> } UIView *result = [self findFirstResponder:childView
r> if (result) return result
r> }return nil;r>