导航控制器中的后退按钮有啥 pushViewController 没有的功能?

Posted

技术标签:

【中文标题】导航控制器中的后退按钮有啥 pushViewController 没有的功能?【英文标题】:What does the back button in a navigation controller do that pushViewController doesn't?导航控制器中的后退按钮有什么 pushViewController 没有的功能? 【发布时间】:2012-02-09 20:17:44 【问题描述】:

在使用 Instruments -> Activity Monitor 测试我的应用程序时,我发现当通过后退按钮完成转换并遵循导航控制器与调用 AppDelegate 中使用 pushViewController 的方法时,内存使用有所不同。如果导航是通过导航返回按钮完成的,那么内存使用量就会下降(我是 ios 编程的新手,但我相信这个术语是它正在释放该特定控制器的子视图)。如果我使用 AppDelegate 中使用 pushViewController 的方法离开该视图控制器,则不会释放内存,如果您返回该视图控制器,它会再次开始累加。我正在为 iOS5 编写 XCode 4.2。

这是AppDelegate中的方法:

-(void)applicationDidTimeout:(NSNotification *) notif

    UIViewController *controller = [[UIStoryboard storyboardWithName:@"MainStoryboard" bundle:NULL] instantiateViewControllerWithIdentifier:@"slideShow"];

    [[UIScreen mainScreen] setBrightness:0.0];
        NSLog(@"go home");
        [(UINavigationController *)self.window.rootViewController pushViewController:controller animated:YES];

应用程序的流程如下:带有 4 个按钮的主页。按钮 1 推送带有滚动视图的 UIViewController,该滚动视图具有子视图 (A)。该子视图还有一个带有关闭按钮的子视图 (B)。点击关闭按钮,子视图(B)将从超级视图中删除。点击左上角的后退按钮,返回主页。如果您在一段时间后没有用户交互,上述方法将触发并将您发送到 screenSaverViewController。触摸屏幕保护程序中的任意位置,即可返回主页。

查看活动监视器时,每次出现子视图(B)时,Real Memory Usage 窗口中报告的已使用内存量都会增加,但在您点击后退按钮并返回主页之前不会下降.如果屏幕保护程序启动,那么它根本不会关闭。

使用任一方法,viewWillDisappear 和 viewDidDisappear 都会在滚动视图控制器中触发。为什么一个释放内存而另一个不释放?

我的所有导航都正常工作,只是内存使用问题需要帮助。

跟进:

picciano 指出了我没有看到的东西——pushViewController 做了它该做的事情。将视图推送到现有视图之上。任何人都可以建议正确替换 pushViewController 吗?该方法必须从 AppDelegate 触发,以便应用在通知触发时从任何视图导航到屏幕保护程序。

已解决:

我最终做的是将导航从 AppDelegate 移动到各个视图控制器。我确保 #import "Timer.h" 并将我的通知侦听器添加到 viewDidLoad [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidTimeout:) name:kApplicationDidTimeoutNotification object:nil]; 然后添加了 applicationDidTimeout: 方法:

-(void)applicationDidTimeout:(NSNotification *) notif

    [self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:1] animated:YES];

1,在这种情况下,是我的屏幕保护程序控制器。 0 = 根视图。这些数字跟随导航堆栈。 root view (0) -> screen saver (1) -> main page (2) -> 1 of 4 other pages

【问题讨论】:

【参考方案1】:

pushViewController(顾名思义)将 UIViewController 的新实例添加到导航控制器中,从而增加整体内存使用量。

相比之下,后退按钮从导航控制器中移除顶部的 UIViewController 并释放内存。

如果你在视图控制器之后继续推送视图控制器,你最终会耗尽内存并崩溃。

重新考虑您的导航。

【讨论】:

这正是正在发生的事情。我应该使用什么来代替 pushViewController?此方法必须将用户发送到屏幕保护程序视图控制器,无论通知触发时他们当前处于什么视图。 @BobbyScon 使用[self presentModalViewController:controller animated:YES]; 显示“屏幕保护程序”视图控制器并使用[self dismissModalViewControllerAnimated:YES]; 关闭它。但不适用于 AppDelegate。只需通过[navController topViewController]; 获取顶部 viewController @MatthiasBauch 我实际上可以将 presentModal 合并到 AppDelegate 中并且它会起作用,但是当调用dismissModal 时(在屏幕保护程序视图中),它会将您放在您离开的地方而不是回到家中屏幕。它确实解决了内存问题,只是不是我需要的成品。感谢您的输入,我会为以后的项目保留它!【参考方案2】:

另一个可能的解决方案是查看一些用于添加、删除或交换子视图的 UIView 方法。

在考虑导航时,有时不错的老式纸笔草图可用于绘制导航模型图。

【讨论】:

谢谢!我确实把这个画出来了。我相信我的导航非常准确,只是屏幕保护程序的调用也会让你回到让我绊倒的主屏幕。这个应用程序适用于在博物馆画廊 24/7 运行的信息亭,所以在一段时间没有用户交互之后,我基本上需要应用程序“重置”。刚刚实施了上述更改,看起来我们很高兴!没有更多的记忆积累。再次感谢您的帖子!

以上是关于导航控制器中的后退按钮有啥 pushViewController 没有的功能?的主要内容,如果未能解决你的问题,请参考以下文章

iOS导航控制器中的后退按钮回调

隐藏 MWPhotoBrowser 导航控制器中的后退按钮

我可以用 xcode 中的“导航控制器后退按钮”传递数据吗

导航栏控制器中的自定义后退按钮

标签栏导航栏中的后退按钮

导航控制器中不显示后退按钮