第一次接觸iOS的開發(fā)人員馍迄,有種強(qiáng)烈的不適感福也,這種不適感來自于在iOS系統(tǒng)里,我們的代碼不是從初始化到釋放內(nèi)存那樣按部就班的完成一系列任務(wù)攀圈,而是像個(gè)乒乓球手一樣暴凑,等待著迎接系統(tǒng)發(fā)來的“球”,接到球時(shí)赘来,我們用較短的代碼片段现喳,完成指定的任務(wù),然后就返回了犬辰,我們似乎沒有“控制權(quán)”嗦篱,我們只是在回答系統(tǒng)的一系列問題,而ViewController的這一系列問題是一組消息幌缝,這組消息告訴我們灸促,視圖將要干什么,已經(jīng)完成了什么,這與UIView形成了巨大的反差腿宰,UIView只關(guān)心“繪圖”呕诉,卻從未擔(dān)心過自己是否已經(jīng)顯示,換句話說吃度,視圖的顯示甩挫、隱藏、設(shè)置大小椿每,不是由UIView自身管理的伊者,這些任務(wù),被劃分給了ViewController间护。
初啼
一個(gè)類的生命周期亦渗,一定從 init...開始,但實(shí)際開發(fā)中汁尺,ViewController的入口幾乎99%是 viewDidLoad法精,這時(shí),初始化已經(jīng)完成痴突,UIViewController的屬性view也已經(jīng)被賦值搂蜓,如果你重寫了loadView,最后也會(huì)調(diào)用viewDidLoad辽装,因此扛点,這是個(gè)初始化子視圖的好地方雕沉,這是因?yàn)椋?/p>
- viewDidLoad 只會(huì)被調(diào)用一次
- 如果使用Autolayout恭理,這時(shí)** 子視圖的 frame 屬性還沒有被設(shè)置植影,沒有被設(shè)置,沒有被設(shè)置** 拓巧,這幾乎是你唯一設(shè)置綁定的時(shí)機(jī)(用編碼方式設(shè)置自動(dòng)布局)斯碌,另一個(gè)時(shí)機(jī)是storyboard中的手動(dòng)綁定,這當(dāng)然在viewDidLoad被調(diào)用之前玲销。
表演時(shí)刻
- (void)viewWillAppear:(BOOL)animated
viewWillAppear總是在viewDidLoad之后被調(diào)用输拇,但不是立即,當(dāng)你只是引用了屬性view贤斜,卻沒有立即把view添加到任何已經(jīng)展示的視圖上時(shí)策吠,viewWillAppear不會(huì)被調(diào)用,這在view被外部引用時(shí)瘩绒,就會(huì)發(fā)生猴抹。當(dāng)然,隨著ViewController的多次推入锁荔,多次進(jìn)入子頁面后返回蟀给,該方法會(huì)被多次調(diào)用。
鎖屏之后會(huì)被調(diào)用嗎?
不會(huì)跋理。viewWillAppear關(guān)注的是view在層次中的顯示與消失择克,鎖屏并沒有改變App本身的層次。
Window疊加后前普,會(huì)被調(diào)用嗎肚邢?
不會(huì)。同鎖屏?xí)r的原因類似拭卿,疊加Window并沒有改變ViewController所在Window的視圖層次骡湖,換句話說,view并沒有被覆蓋或刪除(相對(duì)于自己所在Window)峻厚。
什么時(shí)候animated == YES响蕴?
[self.navigationController pushViewController:subVC animated:YES];
[self presentViewController:subVC animated:YES completion:nil];
視圖顯示后
- (void)viewDidAppear:(BOOL)animated
將被調(diào)用,子視圖有自定義動(dòng)畫時(shí)惠桃,建議在Did方法中啟動(dòng)浦夷,在Will中啟動(dòng)動(dòng)畫時(shí),動(dòng)畫效果將不會(huì)很理想刽射。
視圖被疊加军拟,或移除時(shí)
- viewWillDisappear:
將被調(diào)用
配套的會(huì)調(diào)用- viewDidDisappear:
具體指子視圖控制器是以push和present方法顯示的,父視圖控制器的以上兩個(gè)方法會(huì)被觸發(fā)誓禁。
特別的,addSubview 會(huì)調(diào)用子控制器Appear系列方法肾档,但不會(huì)調(diào)用父視圖viewWillDisappear 方法摹恰。
如下添加子視圖:
XSDViewController *subVC = [[XSDViewController alloc] init];
[self addChildViewController:subVC];
[subVC.view setFrame:self.view.frame];
[self.view addSubview:subVC.view];
[subVC didMoveToParentViewController:self];
得到結(jié)果是,只有 XSDViewController 的 Appear系列方法被調(diào)用怒见,這樣的調(diào)用與push/present方法根本不同是父視圖的View沒有“隱藏”俗慈,只是被覆蓋了。
這說明Appear系列方法是與當(dāng)前控制器的View的顯示/隱藏密切相關(guān)的遣耍。
viewWillAppear 與 viewDidAppear 之間發(fā)生了什么
- viewWillLayoutSubviews
- viewDidLayoutSubviews
將會(huì)被調(diào)用闺阱,
而使用Autolayout時(shí),子視圖大小只有在viewDidLayoutSubviews才真正被設(shè)置好舵变,所以這里才是獲取子視圖大小的正確位置酣溃,常見的錯(cuò)誤是,在viewDidLoad中讀取了某個(gè)view.frame纪隙,用來給其它子視圖賦值赊豌,結(jié)果得到一堆大小“不定”的視圖,甚至可能為零绵咱,在視圖中看不見碘饼!
顯示時(shí)(push)調(diào)用一覽表
- initWithCoder:
- awakeFromNib
- willMoveToParentViewController:
- prefersStatusBarHidden
- preferredStatusBarUpdateAnimation
- loadView
- prepareForSegue:sender:
- viewDidLoad
- extendedLayoutIncludesOpaqueBars
- edgesForExtendedLayout
- viewWillAppear:
- extendedLayoutIncludesOpaqueBars
- edgesForExtendedLayout
- updateViewConstraints
- viewWillLayoutSubviews
- viewDidLayoutSubviews
- (Animation)
- viewDidAppear:
- didMoveToParentViewController:
- updateViewConstraints
- viewWillLayoutSubviews
- viewDidLayoutSubviews
ViewController死亡的原因
死亡不是什么問題,不死才是大問題
——《禪者的初心》
- 系統(tǒng)內(nèi)存不足時(shí),會(huì)收到內(nèi)存警告
didReceiveMemoryWarning
是手動(dòng)釋放內(nèi)存的機(jī)會(huì)艾恼。 - 調(diào)用
dismissViewControllerAnimated: completion:
后住涉,viewDidDisappear
被調(diào)用,最終會(huì)調(diào)用dealloc
钠绍,在ARC中秆吵,這里不必要做release 的工作,卻是檢測(cè)內(nèi)存釋放的好位置五慈,如果一個(gè)控制器從屏幕上已經(jīng)推出纳寂,卻從未調(diào)用dealloc,幾乎可以判定內(nèi)存泄漏泻拦。