日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

iOS APP启动函数调用顺序~详解

發(fā)布時間:2024/3/13 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 iOS APP启动函数调用顺序~详解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

//聯(lián)系人:石虎? QQ: 1224614774昵稱:嗡嘛呢叭咪哄


一、OC調用

C++ 會為靜態(tài)創(chuàng)建的對象生成初始化器,與靜態(tài)語言不同,OC基于Runtime機制可以用類的名字來實例化一個類的對象。Runtime 維護了一張映射類名與類的全局表,當加載一個 dylib 時,其定義的所有的類都需要被注冊到這個全局表中。ObjC 在加載時可以通過 fix-up 在動態(tài)類中改變實例變量的偏移量,利用這個技術可以在不改變dylib的情況下添加另一個 dylib 中類的方法,而非常見的通過定義類別(Category)的方式改變一個類的方法。


主執(zhí)行文件和相關的 dylib的依賴關系構成了一張巨大的有向圖,執(zhí)行初始化器先加載葉子節(jié)點,然后逐步向上加載中間節(jié)點,直至最后加載根節(jié)點。這種加載順序確保了安全性,加載某個 dylib 前,其所依賴的其余 dylib 文件肯定已經被預先加載。最后 dyld 會調用 main() 函數(shù)。main() 會調用 UIApplicationMain(),程序啟動。


二、程序啟動邏輯

使用Xcode打開一個項目,很容易會發(fā)現(xiàn)一個文件--main.m文件,此處就是應用的入口了。程序啟動時,先執(zhí)行main函數(shù),main函數(shù)是ios程序的入口點,內部會調用UIApplicationMain函數(shù),UIApplicationMain里會創(chuàng)建一個UIApplication對象 ,然后創(chuàng)建UIApplicationdelegate對象 —–(您的)AppDelegate ,開啟一個消息循環(huán)(main runloop),每當監(jiān)聽到對應的系統(tǒng)事件時,就會通知AppDelegate。

int?main(int?argc,?char?*?argv[])?{

@autoreleasepool?{

return?UIApplicationMain(argc,?argv,?nil,?NSStringFromClass([AppDelegate?class]));

}

}

UIApplication對象是應用程序的象征,每一個應用都有自己的UIApplication對象,而且是單例的。通過[UIApplication sharedApplication]可以獲得這個單例對象,一個iOS程序啟動后創(chuàng)建的第一個對象就是UIApplication對象, 利用UIApplication對象,能進行一些應用級別的操作。


三、UIApplicationMain函數(shù)實現(xiàn)如下:

int?UIApplicationMain{

?

??int?argc,

???

??char?*argv[],

???

??NSString?*principalClassName,

???

??NSString?*?delegateClassName

???

}

第一個參數(shù)表示參數(shù)的個數(shù),第二個參數(shù)表示裝載函數(shù)的數(shù)組,第三個參數(shù),是UIApplication類名或其子類名,若是nil,則默認使用UIApplication類名。第四個參數(shù)是協(xié)議UIApplicationDelegate的實例化對象名,這個對象就是UIApplication對象監(jiān)聽到系統(tǒng)變化的時候通知其執(zhí)行的相應方法。


啟動完畢會調用 didFinishLaunching方法,并在這個方法中創(chuàng)建UIWindow,設置AppDelegatewindow屬性,并設置UIWindow的根控制器。如果有storyboard,會根據(jù)info.plist中找到應用程序的入口storyboard并加載箭頭所指的控制器,顯示窗口。storyboardxib最大的不同在于storyboard是基于試圖控制器的,而非視圖或窗口。展示之前會將添加rootViewControllerviewUIWindow上面(在這一步才會創(chuàng)建控制器的view


1 [window?addSubview:?window.rootViewControler.view];

每個應用程序至少有一個UIWindow,這window負責管理和協(xié)調應用程序的屏幕顯示,rootViewControllerview將會作為UIWindow的首視圖。




未使用storyboard的啟動


四、程序啟動的完整過程如下:

1.main 函數(shù)

2.UIApplicationMain

  • 創(chuàng)建UIApplication對象
  • 創(chuàng)建UIApplicationdelegate對象
  • delegate對象開始處理(監(jiān)聽)系統(tǒng)事件(沒有storyboard)
  • 程序啟動完畢的時候, 就會調用代理的application:didFinishLaunchingWithOptions:方法
  • application:didFinishLaunchingWithOptions:中創(chuàng)建UIWindow
  • 創(chuàng)建和設置UIWindowrootViewController
  • 顯示窗口

3.根據(jù)Info.plist獲得最主要storyboard的文件名,加載最主要的storyboard(有storyboard)

  • 創(chuàng)建UIWindow
  • 創(chuàng)建和設置UIWindowrootViewController
  • 顯示窗口

五、AppDelegate的代理方法

//app啟動完畢后就會調用

-?(BOOL)application:(UIApplication?*)application?didFinishLaunchingWithOptions:(NSDictionary?*)launchOptions

{

}

?

//app程序失去焦點就會調用????????????????????

-?(void)applicationWillResignActive:(UIApplication?*)application

{

}

?

//app進入后臺的時候調用,?一般在這里保存應用的數(shù)據(jù)(游戲數(shù)據(jù),比如暫停游戲)

-?(void)applicationDidEnterBackground:(UIApplication?*)application

{

}

?

//app程序程序從后臺回到前臺就會調用

-?(void)applicationWillEnterForeground:(UIApplication?*)application

{

}

?

//app程序獲取焦點就會調用

-?(void)applicationDidBecomeActive:(UIApplication?*)application

{

?}

?

//?內存警告,可能要終止程序,清除不需要再使用的內存

-?(void)applicationDidReceiveMemoryWarning:(UIApplication?*)application

{

}

?

//?程序即將退出調用

-?(void)applicationWillTerminate:(UIApplication?*)application

{

}


AppDelegate加載順序

1.application:didFinishLaunchingWithOptions:

2.applicationDidBecomeActive:


ViewController中的加載順序

1.loadView

2.viewDidLoad

3.viewWillAppear

4.viewWillLayoutSubviews

5.viewDidLayoutSubviews

6.viewDidAppear


View中的加載順序

1.initWithCoder(如果沒有storyboard就會調用initWithFrame,這里兩種方法視為一種)

2.awakeFromNib

3.layoutSubviews

4.drawRect


一些方法的使用時機

1 +?(void)load;

應用程序啟動就會調用的方法,在這個方法里寫的代碼最先調用。

1 +?(void)initialize;

用到本類時才調用,這個方法里一般設置導航控制器的主題等,如果在后面的方法設置導航欄主題就太遲了!


1 -?(BOOL)application:(UIApplication?*)application?didFinishLaunchingWithOptions:(NSDictionary*)launchOptions;

這個方法里面會創(chuàng)建UIWindow,設置根控制器并展現(xiàn),比如某些應用程序要加載授權頁面也是在這加,也可以設置觀察者,監(jiān)聽到通知切換根控制器等。


1 -?(void)awakeFromNib;

在使用IB的時候才會涉及到此方法的使用,當.nib文件被加載的時候,會發(fā)送一個awakeFromNib的消息到.nib文件中的每個對象,每個對象都可以定義自己的awakeFromNib函數(shù)來響應這個消息,執(zhí)行一些必要的操作。在這個方法里設置view的背景等一系列普通操作。


1 -?(void)loadView;

創(chuàng)建視圖的層次結構,在沒有創(chuàng)建控制器的view的情況下不能直接寫 self.view 因為self.view的底層是:


if_view?==?nil{

_view?=?[self?loadView]

}

這么寫會直接造成死循環(huán)。

如果重寫這個loadView方法里面什么都不寫,會顯示黑屏。


1 -?(void)viewWillLayoutSubviews;

視圖將要布局子視圖,蘋果建議的設置界面布局屬性的方法,這個方法和viewWillAppear里,系統(tǒng)的底層都是沒有寫任何代碼的,也就是說這里面不寫super 也是可以的。


1 -?(void)layoutSubviews;

在這個方法里一般設置子控件的frame。


1 -?(void)drawRect:(CGRect)rect;

UI控件都是畫上去的,在這一步就是把所有的東西畫上去。drawRect方法只能在加載時調用一次,如果后面還需要調用,比如下載進度的圓弧,需要一直刷幀,就要使用setNeedsDisplay來定時多次調用本方法。

1 -?(void)applicationDidBecomeActive:(UIApplication?*)application;

這是AppDelegate的應用程序獲取焦點方法,真正到了這里,才是所有東西全部加載完畢。


啟動分析

應用啟動時,會播放一個啟動動畫。iPhone上是400msiPad上是500ms。如果應用啟動過慢,用戶就會放棄使用,甚至永遠都不再回來。為了防止一個應用占用過多的系統(tǒng)資源,開發(fā)iOS的蘋果工程師門設計了一個“看門狗”的機制。在不同的場景下,“看門狗”會監(jiān)測應用的性能。如果超出了該場景所規(guī)定的運行間,“看門狗”就會強制終結這個應用的進程。


iOS App啟動時會鏈接并加載Frameworkstatic lib,執(zhí)行UIKit初始化,然后進入應用程序回調,執(zhí)行Core Animation transaction等。每個Framework都會增加啟動時間和占用的內存,不要鏈接不必要的Framework,必要的Framework不要標記為Optional。避免創(chuàng)建全局的C++對象。


初始化UIKit時字體、狀態(tài)欄、user defaultsMain.storyboard會被初始化。User defaults本質上是一個plist文件,保存的數(shù)據(jù)是同時被反序列化的,不要在user defaults里面保存圖片等大數(shù)據(jù)。


對于 OC 來說應盡量減少 Class,selector category 這些元數(shù)據(jù)的數(shù)量。編碼原則和設計模式之類的理論會鼓勵大家多寫精致短小的類和方法,并將每部分方法獨立出一個類別,但這會增加啟動時間。在調用的地方使用初始化器,不要使用\\atribute((constructor)) 將方法顯式標記為初始化器,而是讓初始化方法調用時才執(zhí)行。比如使用 dispatch_once(),pthread_once() std::once()。也就是在第一次使用時才初始化,推遲了一部分工作耗時。


建立網絡連接前需要做域名解析,如果網關出現(xiàn)問題,dns解析不正常時,dns的超時時間是應用控制不了的。在程序設計時要考慮這些問題,如果程序啟動時有網絡連接,應盡快的結束啟動過程,網絡訪問通過線程解決,而不阻塞主線程的運行。



謝謝!!!












總結

以上是生活随笔為你收集整理的iOS APP启动函数调用顺序~详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。