
最近幾天看了好多人的面經(jīng),時(shí)不時(shí)就看到一個(gè)問題:
在A頁面跳轉(zhuǎn)到B頁面的過程中 A 的 viewDidDisappear 方法和 B 的 viewDidAppear 誰先調(diào)用?
其實(shí)我以前一直理所當(dāng)然的認(rèn)為它們的順序就是 A-viewDidDisappear --> B-viewDidAppear,至于為什么會(huì)這么想,就是感覺

今天寫了個(gè)Demo去測(cè)試了一下,發(fā)現(xiàn)完全不是自己想象的那樣,每一種轉(zhuǎn)場(chǎng)(Push,Present,TabBar切換)都是不一樣的。
測(cè)試
我自定義了兩個(gè)類,繼承自UIViewController,為了方便觀察分別叫做A_ViewController,B_ViewController,然后重寫了一系列 appear 和 disappear 方法。
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSLog(@"A view will appear %@",self);
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSLog(@"A view did appear %@",self);
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
NSLog(@"A view will disappear %@",self);
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear: animated];
NSLog(@"A view did disappear %@",self);
}
然后分別用 push, present, 以及 tabbar 的切換來測(cè)試,然后查看打印的結(jié)果。
Push & Pop
--------------------------PUSH-----------------------------
A view will disappear <A_ViewController: 0x7fa11067a730>
B view will appear <B_ViewController: 0x7fa110516530>
A view did disappear <A_ViewController: 0x7fa11067a730>
B view did appear <B_ViewController: 0x7fa110516530>
--------------------------POP-----------------------------
B view will disappear <B_ViewController: 0x7fa110516530>
A view will appear <A_ViewController: 0x7fa11067a730>
B view did disappear <B_ViewController: 0x7fa110516530>
A view did appear <A_ViewController: 0x7fa11067a730>
在這里的調(diào)用順序是和我之前預(yù)想的一樣的,也就是
A-willDisappear --> B-willAppear --> A-didDisappear --> B-didAppear
Present & Dismiss
在模態(tài)的轉(zhuǎn)場(chǎng)中就有一些不一樣的事了。我們知道模態(tài)轉(zhuǎn)場(chǎng)有好多種style,其中有兩種我們需要特別注意的UIModalPresentationCustom,UIModalPresentationOverFullScreen。我們先看一下除了這兩種style以外的轉(zhuǎn)場(chǎng),他們的調(diào)用順序是怎樣的。
-----------------------NormalPresent------------------------
A view will disappear <A_ViewController: 0x7fc2a14ac490>
B view will appear <B_ViewController: 0x7fc2a152a880>
B view did appear <B_ViewController: 0x7fc2a152a880>
A view did disappear <A_ViewController: 0x7fc2a14ac490>
-------------------------DISMISS----------------------------
B view will disappear <B_ViewController: 0x7fc2a152a880>
A view will appear <A_ViewController: 0x7fc2a14ac490>
A view did appear <A_ViewController: 0x7fc2a14ac490>
B view did disappear <B_ViewController: 0x7fc2a152a880>
這里其實(shí)已經(jīng)和push的轉(zhuǎn)場(chǎng)不一樣了。普通模態(tài)的轉(zhuǎn)場(chǎng)的順序是這樣的
A-willDisappear --> B-willAppear --> B-didAppear --> A-didDisappear
再看看前面提到的那兩種特殊的模態(tài)轉(zhuǎn)場(chǎng)。因?yàn)樵谶@兩種方式的轉(zhuǎn)場(chǎng)下A的view是不會(huì)消失的,所以所有與A有關(guān)的 appear 或 disappear 方法都不會(huì)被調(diào)用
-----------------------CustomPresent------------------------
B view will appear <B_ViewController: 0x7f960249bac0>
B view did appear <B_ViewController: 0x7f960249bac0>
-------------------------DISMISS----------------------------
B view will disappear <B_ViewController: 0x7f960249bac0>
B view did disappear <B_ViewController: 0x7f960249bac0>
所以在這兩種style下只有B-willAppear --> B-didAppear
TabBar切換
TabBar 的切換也是一個(gè)很神奇的順序
B view will appear <B_ViewController: 0x7f88cbed7160>
A view will disappear <A_ViewController: 0x7f88cbed6680>
A view did disappear <A_ViewController: 0x7f88cbed6680>
B view did appear <B_ViewController: 0x7f88cbed7160>
與push不同的是,TabBar下,會(huì)先調(diào)用 B 的 willAppear,再調(diào)用 A 的 willDisappear
所以TabBar的順序是這樣的:
B-willAppear --> A-willDisappear --> A-didDisappear --> B-didAppear
總結(jié)
在每一種轉(zhuǎn)場(chǎng)下,appear 與 disappear 都有一些不一樣的順序,一定要分清楚,不能一概而論。
Push: A-willDisappear-->B-willAppear-->A-didDisappear-->B-didAppear
Present: A-willDisappear-->B-willAppear-->B-didAppear-->A-didDisappear
CustomPresent: B-willAppear-->B-didAppear
TabBar: B-willAppear-->A-willDisappear-->A-didDisappear-->B-didAppear
疑惑
為什么要把這個(gè)過程弄的這么復(fù)雜?目前還沒有想法,如果有知道的朋友,希望告知。
