麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

對應(yīng)用程序啟動(dòng)時(shí)所有方法的調(diào)用順序分析

2019-11-14 19:28:53
字體:
供稿:網(wǎng)友

一個(gè)應(yīng)用程序的啟動(dòng)過程要包括代理的創(chuàng)建,控制器的加載和控制器view的加載,這其中有很多關(guān)于生命周期的方法,每個(gè)方法都是有先后順序的,如果調(diào)用順序拿不準(zhǔn),或者某段代碼寫的方法不恰當(dāng),就會(huì)遇到各種奇葩問題。本文不怕麻煩的在幾乎所有啟動(dòng)時(shí)要調(diào)用的方法里都用了 __FUNCTION__ 打印。結(jié)果還有有些地方出人意料的

如果你不是在董鉑然博客園看到本文,請點(diǎn)擊查看原文

首先回顧一下應(yīng)用程序的啟動(dòng)過程

①.先加載Main函數(shù)

②.在Main函數(shù)里的 UIapplicationMain方法中,創(chuàng)建Application對象 創(chuàng)建Application的Delegate對象

③.創(chuàng)建主循環(huán),代理對象開始監(jiān)聽事件

④.啟動(dòng)完畢會(huì)調(diào)用 didFinishLaunching方法,并在這個(gè)方法中創(chuàng)建UIWindow

⑤.設(shè)置UIWindow的根控制器是誰

⑥.如果有storyboard,會(huì)根據(jù)info.plist中找到應(yīng)用程序的入口storyboard并加載箭頭所指的控制器

⑦.顯示窗口

 

本文考慮的時(shí)步驟③之后到步驟⑦結(jié)束時(shí)將要調(diào)用的方法

其中有AppDelegate,ViewController,MainView(控制器的View),ChildView(子控件的View)的18個(gè)方法

AppDelegate中的:

1.application:didFinishLaunchingWithOptions:

2.applicationDidBecomeActive:

 

ViewController中的:

3.loadView

4.viewDidLoad

5.load

6.initialize

7.viewWillAppear

8.viewWillLayoutSubviews

9.viewDidLayoutSubviews

10.viewDidAppear

 

MainView(控制器的View)中的:

11.initWithCoder(如果沒有storyboard就會(huì)調(diào)用initWithFrame,這里兩種方法視為一種)

12.awakeFromNib

13.layoutSubviews

14.drawRect

 

ChildView(子控件View)中的:

15.initWithCoder(如果沒有storyboard就會(huì)調(diào)用initWithFrame,這里兩種方法視為一種)

16.awakeFromNib

17.layoutSubviews

18.drawRect

 

那么問題來了,不往下看你可以把上面的十八個(gè)方法排個(gè)順序么?

 

 

下面的圖是Xcode6.3的beta2版  

有時(shí)有變化也就是最后兩個(gè)方法有點(diǎn)出入

 

我更傾向于Xcode 6.1 覺得更科學(xué) 下面就是對各個(gè)方法的整理

 

+ (void)load;

 1.這是應(yīng)用程序啟動(dòng)就會(huì)調(diào)用的方法,在這個(gè)方法里寫的代碼最先調(diào)用(董鉑然原創(chuàng))

 

+ (void)initialize;

 2.這個(gè)是需要用到本類時(shí)才調(diào)用,這個(gè)方法里一般寫 設(shè)置導(dǎo)航控制器的主題啊 之類的,如果在后面的方法設(shè)置導(dǎo)航欄主題就晚了!(當(dāng)然在上面的方法里也能寫)

 

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

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

 

ChildView - (instancetype)initWithCoder:(NSCoder *)aDecoder; 

4.這里反正我是萬萬沒想到,childView的initwithcoder會(huì)在MainView的方法之前調(diào)用,父的都還沒出來,就先整子控件? 有了解比較透徹的博友懇請告訴我謝謝。

 

MainView - (instancetype)initWithCoder:(NSCoder *)aDecoder;

5.就是關(guān)于應(yīng)用程序的數(shù)據(jù)存儲(chǔ)后的解檔操作。

 

MainView - (void)awakeFromNib;

6.在這個(gè)方法里設(shè)置view的背景等一系列普通操作,不要寫關(guān)于frame的還不準(zhǔn),在使用IB的時(shí)候才會(huì)涉及到此方法的使用,當(dāng).nib文件被加載的時(shí)候,會(huì)發(fā)送一個(gè)awakeFromNib的消息到.nib文件中的每個(gè)對象,每個(gè)對象都可以定義自己的awakeFromNib函數(shù)來響應(yīng)這個(gè)消息,執(zhí)行一些必要的操作。 

 

ChildView - (void)awakeFromNib

7.子控件也有本方法,重寫父類的方法。基本用法同上 

 

- (void)loadView;

 8.創(chuàng)建視圖的層次結(jié)構(gòu),這里需要注意,在沒有創(chuàng)建控制器的view的情況下不能直接寫 self.view 因?yàn)閟elf.view的底層是:

if(_view == nil){

  _view = [self loadView]

}

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

如果重寫這個(gè)loadView方法里面什么都不寫,會(huì)顯示黑屏。

如果寫了[super view]還要看前面的控制器在創(chuàng)建時(shí)是寫的initWithNibName(指定了xib名字),還是寫的普通的init。 如果是后者還是黑屏。

如果不在這個(gè)方法中,init的底層是會(huì)調(diào)用initWithNibName的,如果名字是MainViewController,會(huì)先在項(xiàng)目中找MainView.xib 找不到會(huì)再找MainViewController.xib。 

 

- (void)viewDidLoad;

9.臥槽,這個(gè)方法是當(dāng)年用的最多的方法,但是在之后的開發(fā)中就會(huì)發(fā)現(xiàn)越來越不靠譜,很多東西都還沒加載完畢,各種取值都不準(zhǔn)確,很少在這里面寫東西了。 這里只是把視圖元件加載完成,還沒有開始布局不要設(shè)置關(guān)于 frame 之類的屬性!有時(shí)可能會(huì)出現(xiàn)差20個(gè)像素點(diǎn)等狀況。

 

- (void)viewWillAppear:(BOOL)animated;

10.視圖將要出現(xiàn),這個(gè)方法用的非常多,比如如果要設(shè)置導(dǎo)航欄的setNavigationBarHiden:animate: 就必須要在這里寫,才能完美契合,不卡跳。 還有很多比如監(jiān)聽屏幕旋轉(zhuǎn)啦,

viewWillTransitionToSize:可能要在本方法里再調(diào)一次,或者就是新到這個(gè)界面要reloadData或是自動(dòng)下拉刷新等 都是寫在本方法里。

 

- (void)viewWillLayoutSubviews;

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

 

MainView  - (void)layoutSubviews;

12.在這個(gè)方法里一般設(shè)置子控件的frame,因?yàn)檫@里相當(dāng)于是布局基本完成了,設(shè)置時(shí)取到的frame或者是self.bounds才最準(zhǔn),如果在awakeFromeNib里寫會(huì)不準(zhǔn)確 。還有這里要切記千萬不能把super layoutSubviews忘了,可能最后都很難找到這個(gè)bug

 

- (void)viewDidLayoutSubviews;

13.這個(gè)方法我也是玩玩沒想到,控制器的view的子控件還沒有布局好呢,怎么這個(gè)控制器就已經(jīng)說布局全部完成了?那后邊的布局就不等了? 有獨(dú)到見解的也懇請你告訴我,這其中蘋果的意思到底是什么。 

 

ChildView - (void)layoutSubviews;

14.控制器的子控件里的子控件的布局就在這里寫了。 

 

MainView - (void)drawRect:(CGRect)rect;

15. 因?yàn)槟J(rèn)所有額UI控件都是畫上去的,在這一步就是把所有的東西畫上去,有時(shí)候需要用到Quartz2D的知識(shí)的時(shí)候都是在這個(gè)方法里話,但也是要注意別忘了寫super,不然系統(tǒng)原本的東西就都畫不上來了,這里要建議盡可能使用貝塞爾路徑畫圖形,因?yàn)橄到y(tǒng)默認(rèn)的那個(gè)上下文畫法有時(shí)可能會(huì)內(nèi)存泄露。drawRect方法只能在加載時(shí)調(diào)用一次,如果后面還需要調(diào)用,比如下載進(jìn)度的圓弧,需要一直刷幀,就要使用setNeedsDisplay來定時(shí)多次調(diào)用本方法

 

ChildView - (void)drawRect:(CGRect)rect;

16.view的子控件內(nèi)部的畫圖方法,有時(shí)可以自己自定義label 中間帶個(gè)刪除線的(用來寫打折前的原價(jià)) 就是在這里畫根線 。

 

- (void)viewDidAppear:(BOOL)animated;

17.把上面的畫圖都畫完了,這里就會(huì)顯示,視圖完全加載完成。在這里的操作可能就是設(shè)置頁面的一些動(dòng)畫,或者是設(shè)置tableView,collectionView,QQ聊天頁面啥的滾動(dòng)到底部scrollToIndexPath之類的代碼操作。

 

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

 18.最后這是AppDelegate的應(yīng)用程序獲取焦點(diǎn)方法,真正到了這里,才是所有東西全部加載完畢,應(yīng)用程序整裝待發(fā)保持最佳狀態(tài)等待用戶操作。這個(gè)方法中一般會(huì)寫關(guān)于彈出鍵盤的方法,比如有的用戶登錄界面為了更好的用戶體驗(yàn),就讓你在剛打開程序來到登錄界面的時(shí)候,光標(biāo)的焦點(diǎn)就自動(dòng)在賬號的文本框里閃爍,也就是設(shè)置賬號文本框?yàn)榈谝豁憫?yīng)者。鍵盤在頁面加載完畢后從下方彈出,這種代碼一般就在本方法寫。

 

如果你不是在董鉑然博客園看到本文,請點(diǎn)擊查看原文

以上總結(jié),有不同意見的歡迎交流,歡迎關(guān)注 


發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: av电影网站在线 | av在线1| 北原夏美av| 日韩欧美动作影片 | www.99av| 国产va在线观看免费 | 欧美女优一区 | 国产精品欧美久久久久一区二区 | av电影在线观看网址 | 亚洲精品7777xxxx青睐 | 91久久国产 | 欧美一级毛片特黄黄 | 欧美亚洲国产成人综合在线 | 国内精品一级毛片免费看 | 国产剧情在线观看一区二区 | 日韩视频1 | 成人毛片在线免费看 | 亚洲精品动漫在线观看 | 精品一区二区电影 | 在线视频观看一区二区 | 亚洲免费永久 | 成人在线精品视频 | 超碰99在线观看 | 久久精品国产99久久久古代 | 最新一区二区三区 | 欧美三区在线 | 色阁阁69婷婷 | 久色乳综合思思在线视频 | 特级毛片a级毛片100免费 | 在线a亚洲视频播放在线观看 | 免费毛片视频播放 | 免费观看国产视频 | xxxⅹ96日本护士hd | 国产成人精品一区在线播放 | 欧美一级aa免费毛片 | 国产69精品久久久久孕妇黑 | 色播视频在线播放 | 国产精品一区在线看 | 失禁高潮抽搐喷水h | 亚洲99 | 黄色片网站免费 |