导航控制器溢出
我设计并构建了基于 UINavigationController 的游戏。我有几个像图片上那样的 ViewController。您从 RootVC 中选择 NewGame,然后就可以开始玩了。完成后,您要求转到 NextBoardVC 中的下一个板。完成 10 块板后,您将通过 NextLevelVC 进入下一个级别。有 5 个级别。每个级别包含 10 个板。问题是我使用 PushViewController 方法推送每个 ViewController。 5 个级别后,堆栈上有 52 个 VC,有时应用程序会崩溃。
GameVC 包含很多 png 和一些声音,所以它相当重。我没有任何泄漏(由 Instruments 测试)
抱歉,我没有声誉,所以我无法通过 stackoverflow 上传图像。
这是一张图片:
视图层次结构的文本表示:
RootVC
--OptionsVC
--HowToPlayVC
--NewGameVC
--GameVC
--NextBoardVC
--NextLevelVC
--GameVC
--NextBoardVC
--NextLevelVC
--GameVC
--NextBoardVC
--NextLevelVC
--GameVC
--... and so on many times
是否有更好的方法来进行导航并消除崩溃?
I've designed and build game based on UINavigationController. I have several ViewControllers like on the picture. You select NewGame from RootVC and you are ready to play. After finishing, you are asking to go to the next board in NextBoardVC. After 10 boards you are going to next level by NextLevelVC. There is 5 Levels. Each level contains 10 boards. The problem is that I'm pushing each ViewController using pushViewController method. After 5 levels I have 52 VCs on the stack and sometimes application crashes.
GameVC contains many png's, and some sounds so it's quite heavy. I don't have any leaks (tested by Instruments)
Sorry, I dont have reputation so I cant upload images by stackoverflow.
This is an image:
Textual representation of the view hierarchy:
RootVC
--OptionsVC
--HowToPlayVC
--NewGameVC
--GameVC
--NextBoardVC
--NextLevelVC
--GameVC
--NextBoardVC
--NextLevelVC
--GameVC
--NextBoardVC
--NextLevelVC
--GameVC
--... and so on many times
Is there better way to do the navigation, and eliminate crashes?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
为什么不直接弹出控制器而不是只是将越来越多的控制器推到顶部,特别是在您返回“循环”的那些点上?
Why don't you just pop the controllers back off instead of just pushing more and more controllers on top, especially at those points where you're returning in your "loop"?
不要忘记,您可以使用
setViewControllers:(NSArray *)viewControllersAnimated:(BOOL)animated
直接在导航堆栈上设置视图控制器。因此,您不必将新级别推送到导航堆栈上,而是可以通过创建一个包含所有视图控制器以及新级别的数组,并使用上面的
setViewControllers
方法,将一个级别替换为下一个级别。Don't forget that you can directly set view controllers on a navigation stack, using
setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated
.So rather than pushing new levels onto the navigation stack you could replace one level with the next one by creating an array containing all your view controller up to that point plus your new level, and using the
setViewControllers
method above.您错误地管理了视图控制器层次结构。导航控制器永远不应该像您的图表所建议的那样有循环。
此外,导航控制器应该首先管理视觉层次结构,然后再管理逻辑层次结构。例如,联系人应用程序,其中组列表视图推送联系人列表,联系人列表推送联系人详细信息,联系人详细信息推送多个属性详细信息编辑视图之一。每次离开一个视图时,您都会弹出该视图并“向上”返回层次结构到上一个视图。您永远不会仅通过将另一个联系人详细信息视图推到最后一个合同详细信息视图之上来配置它从一个联系人详细信息视图到下一个联系人视图。
同样,您需要在推送下一个之前从堆栈中弹出现有的
BoardVC
或LevelVC
。(键:此处 --> 表示推送,<-- 表示弹出)
要设置新游戏的第一个级别,您需要:
... 然后添加下一个级别,您首先需要:
... 获得:
...然后:
...对所有其他级别重复。您可以根据需要对每个
BoardVC
执行相同的操作。这里的技巧是不使用默认导航控制器过渡的幻灯片过渡。该转换告诉用户期望这种逻辑布局:
...这就是导致您的问题的原因。相反,请使用另一种过渡,例如淡入淡出或将过渡全部隐藏。
通过弹出用户导航不需要的任何视图,您可以确保视图控制器堆栈在任何时候都不会超过 5 个视图控制器,因此内存中只需要 5 个视图控制器。
You are managing your view controller hierarchy incorrectly. A navigation controller should never have a loop as your diagram suggest yours does.
Also, a navigation controller should managed a visual hierarchy first and logical one second. E.g. The contact app, where a group list view pushes a list of contacts which pushes a contact detail which pushes one of several attribute detail edit views. Everytime you leave one view you pop that view and go back "up" the hierarchy to the previous view. You would never configure it go from one contact detail view to the next contact view just by pushing another contact detail view on top of the last contract detail view.
Likewise you need to pop the existing
BoardVC
orLevelVC
from the stack before pushing the next.(Key: here --> means push and <-- means pop)
To setup a the first level of a new game you would:
... and then to add the next level you would first:
... to get:
... and then:
... repeat for all other levels. You can do the same for each
BoardVC
as needed.The trick here is to not use the slide transition which is the default navigation controller transition. That transition tells the user to expect this logical layout:
... which is what is causing your problem. Instead, use another transition like fade or hide the transition all together.
By popping any views that are not necessary for the user's navigation, you ensure that you view controller stack is never more than 5 view controllers deep at anyone time and that therefore only 5 view controllers are needed in memory.