简体   繁体   English

导航控制器中的后退按钮与pushViewController没有什么关系?

[英]What does the back button in a navigation controller do that pushViewController doesn't?

When testing my app using Instruments -> Activity Monitor, I'm seeing a difference in memory use when a transition is done via the back button and follows the navigation controller vs calling a method in AppDelegate that uses pushViewController . 当使用Instruments - > Activity Monitor测试我的应用程序时,我看到通过后退按钮完成转换并跟随导航控制器与调用AppDelegate中使用pushViewController的方法时内存使用的差异。 If the navigation is completed by the navigation back button, then the memory use drops (I'm new to iOS programming, but I believe the term is that it's releasing the subviews of that particular controller). 如果通过导航后退按钮完成导航,则内存使用会下降(我是iOS编程新手,但我相信这个术语是它正在发布该特定控制器的子视图)。 If I navigate away from that view controller by using a method in AppDelegate that uses pushViewController , then the memory isn't released and if you go back to that view controller, it starts adding up again. 如果我通过使用appDelegate中使用pushViewController的方法离开该视图控制器,那么内存不会被释放,如果你回到那个视图控制器,它会再次开始加起来。 I'm working in XCode 4.2 writing for iOS5. 我正在为iOS5编写XCode 4.2。

This is the method in AppDelegate: 这是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];
}

The app flows like this: Main Page with 4 buttons. 应用程序流程如下:主页面有4个按钮。 Button 1 pushes a UIViewController with a scrollview which has a subview (A). 按钮1使用具有子视图(A)的scrollview推送UIViewController。 That subview also has a subview (B) with a close button. 该子视图还有一个带有关闭按钮的子视图(B)。 Hit the close button and subview(B) is removed from superview. 点击关闭按钮,从超级视图中删除子视图(B)。 Hit the back button on the top left and it returns to the Main Page. 点击左上角的后退按钮,返回主页面。 If you have no user interaction after a set period of time, the method above fires and send you to screenSaverViewController. 如果在一段时间后没有用户交互,则上面的方法将触发并发送给screenSaverViewController。 Touch anywhere in the screen saver and you go back to Main Page. 触摸屏幕保护程序中的任意位置,然后返回主页面。

When watching the Activity Monitor, the amount of memory being reported as used in the Real Memory Usage window increases every time a subview(B) appears, but doesn't go down until you hit the back button and return to Main Page. 在观察活动监视器时,每次出现子视图(B)时,“实内存使用情况”窗口中报告的内存量会增加,但在您点击后退按钮并返回主页面之前不会下降。 If the screen saver kicks in, then it doesn't go down at all. 如果屏幕保护程序启动,那么它根本不会消失。

Using either method, viewWillDisappear and viewDidDisappear both fire in the scrollview Controller. 使用任一方法,viewWillDisappear和viewDidDisappear都会在scrollview Controller中触发。 Why does one release memory and the other doesn't? 为什么一个释放内存而另一个没有?

All of my navigations work, it's just a memory usage issue that I need assistance with. 我的所有导航都有效,这只是我需要帮助的内存使用问题。

Follow Up: 跟进:

picciano pointed out what I wasn't seeing - pushViewController does what it does. picciano指出了我没有看到的东西 - pushViewController做了它的功能。 Pushes views on top of existing views. 在现有视图之上推送视图。 Can anyone suggest the proper replacement for pushViewController? 任何人都可以建议正确替换pushViewController? The method has to fire from AppDelegate so that the app navigates from any view to the screen saver when the notification fires. 该方法必须从AppDelegate触发,以便应用程序在通知触发时从任何视图导航到屏幕保护程序。

Solved: 解决了:

What I ended up doing was moving the navigation from AppDelegate to the individual view controllers. 我最终做的是将导航从AppDelegate移动到各个视图控制器。 I made sure to #import "Timer.h" and added my notification listener to viewDidLoad [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidTimeout:) name:kApplicationDidTimeoutNotification object:nil]; 我确保#import "Timer.h"并将我的通知监听器添加到viewDidLoad [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidTimeout:) name:kApplicationDidTimeoutNotification object:nil]; and then added the applicationDidTimeout: method: 然后添加了applicationDidTimeout:方法:

-(void)applicationDidTimeout:(NSNotification *) notif
{
    [self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:1] animated:YES];
}

1, in this case, is my screen saver controller. 1,在这种情况下,是我的屏幕保护程序控制器。 0 = the root view. 0 =根视图。 These numbers follow the navigation stack. 这些数字跟随导航堆栈。 root view (0) -> screen saver (1) -> main page (2) -> 1 of 4 other pages

pushViewController (like the name implies) add a new instance of a UIViewController into the navigation controller, increasing overall memory usage. pushViewController(顾名思义)将UIViewController的新实例添加到导航控制器中,增加了整体内存使用量。

The back button by contrast removes the top UIViewController from the navigation controller and releases memory. 相反,后退按钮从导航控制器中删除顶部UIViewController并释放内存。

If you continue pushing view controller after view controller, you will eventually run out of memory and crash. 如果在视图控制器之后继续推送视图控制器,最终将耗尽内存并崩溃。

Rethink your navigation. 重新思考你的导航。

Another potential solution is to have a look at some of the UIView methods for adding, removing, or exchanging subviews. 另一个可能的解决方案是查看一些用于添加,删除或交换子视图的UIView方法。

When thinking about navigation, sometimes good old fashioned paper and pencil sketches are useful to diagram your navigation model. 在考虑导航时,有时候好的旧式纸和铅笔素描对您的导航模型有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM