前言
-
View Hierarchy: 從字面上理解就是視圖的分層.可能這樣說,你還有點(diǎn)迷惑.但是如果你的Xcode是version6.0以上的, 你肯定看到過或者用過下面這個(gè)玩意Debug View Hierarchy:
Debug View Hierarchy

Debug View Hierarchy
- 我們?yōu)槭裁匆私釼iew Hierarchy呢? 舉一個(gè)很簡單的例子吧, 如果你解決過足夠多的bug或者踩過很多的坑,那你一定遇到過
ios attempt to present whose view is not in the window hierarchy或者Warning: Attempt to present on whose view is not in the window hierarchy!
View Hierarchy詳解
- 這是我在網(wǎng)上找的一張圖, 比較直觀

View Hierarchy
- 如上圖所示, 可以把View Hierarchy看成翻轉(zhuǎn)的樹結(jié)構(gòu), 而window就是樹的根節(jié)點(diǎn), 而下面的view之間的關(guān)系就對應(yīng)這subviews和superview的關(guān)系.
- 此時(shí)我們點(diǎn)進(jìn)UIView的頭文件, 在下方可以找到view的類擴(kuò)展
@interface UIView(UIViewHierarchy),我們就可以根據(jù)上圖理出View Hierarchy中的view的三種屬性定義關(guān)系-
superview, view的父視圖 -
subviews, view的子視圖集合 -
window, 包含view的container
-
@property(nullable, nonatomic,readonly) UIView *superview;
@property(nonatomic,readonly,copy) NSArray<__kindof UIView *> *subviews;
@property(nullable, nonatomic,readonly) UIWindow *window;
- View Hierarchy還是
Responder Chain的非常重要的部分, 當(dāng)Responder Chain通過responder對象將處理事件的責(zé)任傳遞給下一個(gè)更高級的對象,即當(dāng)前responder對象的nextResponder的時(shí)候,如果此時(shí)需要渲染window, 系統(tǒng)就會根據(jù) View Hierarchy來檢測views的layer的層次來判斷需要進(jìn)行渲染的部分,從而避免每次都重復(fù)渲染同一部分.
ios attempt to present whose view is not in the window hierarchy和Warning: Attempt to present on whose view is not in the window hierarchy!
- 我舉一個(gè)前段時(shí)間, 我身邊的一個(gè)朋友犯的一個(gè)錯(cuò)誤吧作為例子吧.當(dāng)接收到遠(yuǎn)程推送的時(shí)候的時(shí)候, 在
AppDelegate.m中用之前定義好的一個(gè)UIViewController直接present到目標(biāo)控制器, 然后再目標(biāo)控制器取出UIWindow的rootViewController進(jìn)行present.然后就報(bào)了上面的錯(cuò). - 這種錯(cuò)誤可以用一個(gè)通俗易懂的例子: 空中閣樓.在沒有地基,沒有第一層/第二層的情況下, 直接妄圖搭建第三層樓.
- 解決方法: 如果是類似我舉的例子的情況, 可以直接使用當(dāng)前的控制器進(jìn)行present, 或者在控制器的
viewDidAppear中去present.
聯(lián)系我
<a >github</a>
<a >微博</a>
<a href="http://www.itdecent.cn/users/9723687edfb5/latest_articles">簡書</a>
