IOS —— App啓動原理及代碼優化

哈嘍,很久不見。最近處於心情低迷期就沒怎麼來更新文章了。性能優化

在下也算是個半路出家的代碼家,從以前的文章更新到如今app

依然是仍是從基礎學起,萬物歸基礎!oop

因此從今天起天天回來更新彙報學習成果!!天天佈局

今天主要接觸的是Application相關的知識,包括App啓動原理,以及windos窗口控制以及Appdelegate的模塊優化等~ 性能


1.App啓動原理

在咱們建立項目時,有個不起眼的main.m文件,裏頭只有一個方法,返回的也只有一個int對象。在我剛接觸IOS學識時,這一個不起眼的文件常常給我分類放在了一個文件夾裏。學習

具體有什麼用並無深究,可是我只知道的是沒回報錯都是從main文件裏傳出來的。優化

那麼main.m文件到底蘊含着什麼東西呢?spa

int main(int argc, char * argv[]) {
  @autoreleasepool  {
    return UIApplicationMain(argc , argv , nil , NSStringFromClass([Appdelegate clasee]));    
  }  
}

Main文件中返回了一個UIApplicationMain對象,UIApplicationMain可厲害了線程

他幹了這麼幾件事情code

1.建立了 UIApplication 應用對象

2.建立了Application delegate(AppDelegate) 對象

3.創建了一個Event Loop (建立了Runloop對象而且開啓事件循環)

4.讀取info.plist文件

5.基於以上對象(UIApplication、AppDelegate、Runloop)建立一個windos

 

 

而且他自己就是一個死循環。爲何呢?

這得從事件循環,也就是Runloop對象提及。

蘋果的系統誇張的說,就是對Event loop的實現所創建的

當應用啓動時 - >開啓一個死循環Runloop 

當頁面靜止時 -> Runloop處於wait狀態。

當觸發事件時 ->判斷事件來源(handle_msg),

根據來源處理觸發事件

1.定時器

2.GCD

3.Source1

處理結束後,繼續進入等待狀態或者應用結束退出循環。

簡要地說就是這麼一個周而復始的過程(具體能夠看第一篇關於RunLoop的白話文)

 

這裏可能有人會作一個小小的質疑,你說死循環就死循環?怎麼證實給咱們看?

也能夠

int main(int argc, char * argv[]) {
  @autoreleasepool  {
      int back = UIApplicationMain(argc , argv , nil , NSStringFromClass([Appdelegate clasee]));          
      NSLog(@"back == %d",back);
      return back;
  }  
}    

這裏將UIApplicationMain拆分紅int對象而且打印他。

由於他是死循環的緣故因此NSLog並不會打印出來(不信你能夠試一下)。

 

講了那麼多關於ApplicationMain的東西,到底和代碼優化有什麼關係呢?

在說優化以前,還得講到的一個特殊的東西,UIWindos

衆所周知,在IOS的APP中windos一般只有一個,是一種特殊的UIView。

UIWindos有屬於自身的層級對象UIWindosLevel,UIWindosLevel的屬性有三,對應關係以下

UIWindosLevelAlert  > UIWindosLevelStatusBar > UIWindosLevelNormal

雖然話說Windos一般只有一個,可是並非不可建立的,以上的屬性就是對於建立多個windos時,可用於控制層級顯示。 

windos的做用呢,就是加載視圖,就相似app中裏面的電視機。少了他App什麼都不是。

 

那麼Windos怎麼建立呢? 這是application的子類的中的方法

static UIWindow *__xgWindows;

@implementation AppDelegate (XGApp)

- (void)startLoadAd
{
    __xgWindows = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
    
    __xgWindows.rootViewController = [XgADViewController new];
    
    __xgWindows.windowLevel = UIWindowLevelAlert;
    
    [__xgWindows makeKeyAndVisible];
    
//    [self performSelector:@selector(finishWindos) withObject:nil afterDelay:3];
    
    NSLog(@"加載廣告頁");
}

 

刪除呢?只須要設置監聽對象,觸發方法將Windos設置爲nil便可。

如下是觸發方法。

- (void)finishWindos
{
    NSLog(@"關閉Windos");
    __xgWindows = nil;
}

 

 

這裏咱們能夠根據代碼分析得知,咱們是能夠建立application的子類,來進行許多業務的處理。

上述例子咱們運用application的子類GgApplication建立了一個廣告頁,並在三秒銷燬了。在主線程的application didFinishLaunchingWithOptions~方法中

只用了一行代碼就解決了,通常來講在Application裏,由於Delegate的方法是啓動的一部分,因此代碼過於擁擠的話是會影響可視性以及啓動的速度的。

因此在可拆分的狀況下,業務儘量的多的拆分到子類中處理時有助於提升性能的!

在第一個視圖中,不相關的數據處理,均可以放到線程中處理(比較耗時的任務)*(省,市)數據加載

須要注意的是,邏輯必須的清晰。由於APPDelegate是啓動的一部分,稍有差錯是會影響總體運做流暢性的。

若是總體啓動過慢,APP開啓時間 ≥ 5s 時, 蘋果官方甚至會將整個App打回不容許上架。這是須要注意的。


2.代碼優化

關於啓動時間的優化,這邊給出一小部分公式但願能幫助到讀者。

啓動的時間 = T1 + T2

T1(Main方法執行前) 系統環境佈局時間:建立進程、加載分析可執行文件(庫加載、堆棧環境配置等)

T2(Main方法執行後):從Main方法執行到第一個界面顯示的時間

其中有如下四點是影響啓動速度的

1.庫加載越多,啓動越慢

2.Objc類越多,啓動越慢

3.靜態對象全局對象越多、啓動越慢

4.Objc的 +load 越多,啓動越慢

在性能優化方面上更能人爲把控的:loadT2時間

load: 是在加載過程當中,ViewController中的Load方法是自動執行在main方法前的,若是加載對象及方法過多,啓動也會隨之更慢。

因此能夠拆分的業務,儘量拆分處理!

T2時間:能不作數據處理儘量不作,將耗時任務交由線程處理!

 


 

彙報完畢,咱們明天見

相關文章
相關標籤/搜索