iOS App的生命周期

iOS程序的啟動(dòng)執(zhí)行順序

程序啟動(dòng)順序圖

iOS啟動(dòng)原理圖

具體執(zhí)行流程

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

NSLog(@"---?%s?---",__func__);//__func__打印方法名

returnYES;

}

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

NSLog(@"---?%s?---",__func__);

}

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

NSLog(@"---?%s?---",__func__);

}

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

NSLog(@"---?%s?---",__func__);

}

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

NSLog(@"---?%s?---",__func__);

}

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

NSLog(@"---?%s?---",__func__);

}

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

NSLog(@"---?%s?---",__func__);

}

啟動(dòng)程序

-[AppDelegate?application:didFinishLaunchingWithOptions:]

-[AppDelegate?applicationDidBecomeActive:]

按下 Command + H + SHIFT

-[AppDelegate?applicationWillResignActive:]

-[AppDelegate?applicationDidEnterBackground:]

重新點(diǎn)擊 進(jìn)入程序

-[AppDelegate?applicationWillEnterForeground:]

-[AppDelegate?applicationDidBecomeActive:]

內(nèi)存警告

1-[AppDelegate?applicationDidReceiveMemoryWarning:]

UIViewController 的生命周期

//?非storyBoard(xib或非xib)都走這個(gè)方法

-?(instancetype)initWithNibName:(NSString?*)nibNameOrNil?bundle:(NSBundle?*)nibBundleOrNil?{

NSLog(@"%s",?__FUNCTION__);

if(self?=?[superinitWithNibName:nibNameOrNil?bundle:nibBundleOrNil])?{

}

returnself;

}

//?storyBoard走這個(gè)方法

-?(instancetype)initWithCoder:(NSCoder?*)aDecoder?{

NSLog(@"%s",?__FUNCTION__);

if(self?=?[superinitWithCoder:aDecoder])?{

}

returnself;

}

//?xib?加載?完成

-?(void)awakeFromNib?{

[superawakeFromNib];

NSLog(@"%s",?__FUNCTION__);

}

//?加載視圖(默認(rèn)從nib)

-?(void)loadView?{

NSLog(@"%s",?__FUNCTION__);

self.view?=?[[UIView?alloc]?initWithFrame:[UIScreen?mainScreen].bounds];

self.view.backgroundColor?=?[UIColor?redColor];

}

//?視圖控制器中的視圖加載完成,viewController自帶的view加載完成

-?(void)viewDidLoad?{

NSLog(@"%s",?__FUNCTION__);

[superviewDidLoad];

}

//?視圖將要出現(xiàn)

-?(void)viewWillAppear:(BOOL)animated?{

NSLog(@"%s",?__FUNCTION__);

[superviewWillAppear:animated];

}

//?view?即將布局其?Subviews

-?(void)viewWillLayoutSubviews?{

NSLog(@"%s",?__FUNCTION__);

[superviewWillLayoutSubviews];

}

//?view?已經(jīng)布局其?Subviews

-?(void)viewDidLayoutSubviews?{

NSLog(@"%s",?__FUNCTION__);

[superviewDidLayoutSubviews];

}

//?視圖已經(jīng)出現(xiàn)

-?(void)viewDidAppear:(BOOL)animated?{

NSLog(@"%s",?__FUNCTION__);

[superviewDidAppear:animated];

}

//?視圖將要消失

-?(void)viewWillDisappear:(BOOL)animated?{

NSLog(@"%s",?__FUNCTION__);

[superviewWillDisappear:animated];

}

//?視圖已經(jīng)消失

-?(void)viewDidDisappear:(BOOL)animated?{

NSLog(@"%s",?__FUNCTION__);

[superviewDidDisappear:animated];

}

//?出現(xiàn)內(nèi)存警告

-?(void)didReceiveMemoryWarning?{

NSLog(@"%s",?__FUNCTION__);

[superdidReceiveMemoryWarning];

}

//?視圖被銷毀

-?(void)dealloc?{

NSLog(@"%s",?__FUNCTION__);

}

分析

initWithNibName:bundle:

初始化UIViewController,執(zhí)行關(guān)鍵數(shù)據(jù)初始化操作,非StoryBoard創(chuàng)建UIViewController都會(huì)調(diào)用這個(gè)方法。

注意: 不要在這里做View相關(guān)操作,View在loadView方法中才初始化。

initWithCoder:

如果使用StoryBoard進(jìn)行視圖管理,程序不會(huì)直接初始化一個(gè)UIViewController,StoryBoard會(huì)自動(dòng)初始化或在segue被觸發(fā)時(shí)自動(dòng)初始化,因此方法initWithNibName:bundle不會(huì)被調(diào)用,但是initWithCoder會(huì)被調(diào)用。

awakeFromNib

當(dāng)awakeFromNib方法被調(diào)用時(shí),所有視圖的outlet和action已經(jīng)連接,但還沒有被確定,這個(gè)方法可以算作適合視圖控制器的實(shí)例化配合一起使用的,因?yàn)橛行┬枰鶕?jù)用戶喜好來進(jìn)行設(shè)置的內(nèi)容,無法存在storyBoard或xib中,所以可以在awakeFromNib方法中被加載進(jìn)來。

loadView

當(dāng)執(zhí)行到loadView方法時(shí),如果視圖控制器是通過nib創(chuàng)建,那么視圖控制器已經(jīng)從nib文件中被解檔并創(chuàng)建好了,接下來任務(wù)就是對(duì)view進(jìn)行初始化。

loadView方法在UIViewController對(duì)象的view被訪問且為空的時(shí)候調(diào)用。這是它與awakeFromNib方法的一個(gè)區(qū)別。

假設(shè)我們在處理內(nèi)存警告時(shí)釋放view屬性:self.view = nil。因此loadView方法在視圖控制器的生命周期內(nèi)可能被調(diào)用多次。

loadView方法不應(yīng)該直接被調(diào)用,而是由系統(tǒng)調(diào)用,它會(huì)加載或創(chuàng)建一個(gè)view并把它賦值給UIViewController的view屬性。

在創(chuàng)建view的過程中,首先會(huì)根據(jù)nibName去找對(duì)應(yīng)的nib文件然后加載。如果nibName為空或找不到對(duì)應(yīng)的nib文件,則會(huì)創(chuàng)建一個(gè)空視圖(這種情況一般是純代碼)

注意:在重寫loadView方法的時(shí)候,不要調(diào)用父類的方法。

viewDidLoad

當(dāng)loadView將view載入內(nèi)存中,會(huì)進(jìn)一步調(diào)用viewDidLoad方法來進(jìn)行進(jìn)一步設(shè)置。此時(shí),視圖層次已經(jīng)放到內(nèi)存中,通常,我們對(duì)于各種初始化數(shù)據(jù)的載入,初始設(shè)定、修改約束、移除視圖等很多操作都可以這個(gè)方法中實(shí)現(xiàn)。

viewWillAppear

系統(tǒng)在載入所有的數(shù)據(jù)后,將會(huì)在屏幕上顯示視圖,這時(shí)會(huì)先調(diào)用這個(gè)方法,通常我們會(huì)在這個(gè)方法對(duì)即將顯示的視圖做進(jìn)一步的設(shè)置。比如,設(shè)置設(shè)備不同方向時(shí)該如何顯示;設(shè)置狀態(tài)欄方向、設(shè)置視圖顯示樣式等。

另一方面,當(dāng)APP有多個(gè)視圖時(shí),上下級(jí)視圖切換是也會(huì)調(diào)用這個(gè)方法,如果在調(diào)入視圖時(shí),需要對(duì)數(shù)據(jù)做更新,就只能在這個(gè)方法內(nèi)實(shí)現(xiàn)。

viewWillLayoutSubviews

view即將布局其Subviews。 比如view的bounds改變了(例如:狀態(tài)欄從不顯示到顯示,視圖方向變化),要調(diào)整Subviews的位置,在調(diào)整之前要做的工作可以放在該方法中實(shí)現(xiàn)

viewDidLayoutSubviews

view已經(jīng)布局其Subviews,這里可以放置調(diào)整完成之后需要做的工作。

viewDidAppear

在view被添加到視圖層級(jí)中以及多視圖,上下級(jí)視圖切換時(shí)調(diào)用這個(gè)方法,在這里可以對(duì)正在顯示的視圖做進(jìn)一步的設(shè)置。

viewWillDisappear

在視圖切換時(shí),當(dāng)前視圖在即將被移除、或被覆蓋是,會(huì)調(diào)用該方法,此時(shí)還沒有調(diào)用removeFromSuperview。

viewDidDisappear

view已經(jīng)消失或被覆蓋,此時(shí)已經(jīng)調(diào)用removeFromSuperView;

dealloc

視圖被銷毀,此次需要對(duì)你在init和viewDidLoad中創(chuàng)建的對(duì)象進(jìn)行釋放。

didReceiveMemoryWarning

在內(nèi)存足夠的情況下,app的視圖通常會(huì)一直保存在內(nèi)存中,但是如果內(nèi)存不夠,一些沒有正在顯示的viewController就會(huì)收到內(nèi)存不足的警告,然后就會(huì)釋放自己擁有的視圖,以達(dá)到釋放內(nèi)存的目的。但是系統(tǒng)只會(huì)釋放內(nèi)存,并不會(huì)釋放對(duì)象的所有權(quán),所以通常我們需要在這里將不需要顯示在內(nèi)存中保留的對(duì)象釋放它的所有權(quán),將其指針置nil。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容