弹出时UIViewController不会从内存中释放

时间:2014-03-14 15:36:33

标签: ios objective-c memory-management uiviewcontroller uinavigationcontroller

我有一个UINavigationController并且我试图在每个UIViewController时从内存释放一旦另一个在堆栈顶部。我将viewControllers的{​​{1}}属性分配给新UINavigationController,然后将其弹出。这样我在堆栈中总是只有一个UIViewController。但是,每次创建新UIViewController时,内存都会不断累加。调用Dealloc,但内存使用情况保持不变。

您可以下载示例项目HERE

FirstViewController.h

UIViewController

FirstViewController.m

#import "SecondViewController.h"

@interface FirstViewController : UIViewController

-(IBAction)goToSecond:(id)sender;

@end

SecondViewController.h

#import "FirstViewController.h"

@interface FirstViewController ()

@end

@implementation FirstViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSLog(@"%@", self.navigationController.viewControllers);

}

-(void)goToSecond:(id)sender{

    SecondViewController *secondVC = [[SecondViewController alloc]init];
    [self.navigationController setViewControllers:@[secondVC]];
    [self.navigationController popViewControllerAnimated:NO];
}

-(void)dealloc{

    NSLog(@"FirstVC dealloc");
}
@end

SecondViewController.m

#import "FirstViewController.h"

@interface SecondViewController : UIViewController

-(IBAction)goToFirst:(id)sender;

@end

6 个答案:

答案 0 :(得分:0)

不应按预期使用导航控制器。 您应该调用pushViewControllerpopViewController来显示/解除您的viewControllers。 如果您遇到内存问题,请尝试在didReceiveMemoryWarning回拨

中释放内存

答案 1 :(得分:0)

我不确定uinavigationcontroller的好处,但无论如何你可以在你的uiviewcontrollers .m上添加这个片段

-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];    
    if (self.navigationController.viewControllers.count > 1) {
        NSMutableArray *newViewControllers = [NSMutableArray arrayWithArray:self.navigationController.viewControllers];
        [newViewControllers removeObject:[controllers objectAtIndex:1]];
        self.navigationController.viewControllers = newViewControllers;
    }
}

而不是

[self.navigationController setViewControllers:@[firstVC]];
[self.navigationController popViewControllerAnimated:NO];

你可以设置

[self.navigationController pushViewController:[[FirstViewController alloc] init] animated:NO];

答案 2 :(得分:0)

您正在使用pop进一步,但如果您想转到下一个push,则需要使用ViewController

-(void)goToSecond:(id)sender{
    SecondViewController *secondVC = [[SecondViewController alloc]init];
    [ self.navigationController pushViewController:secondVC animated:YES];
}

SecondViewController回到FirstViewController,你应该使用pop

-(void)backToController
{
    [self.navigationController popViewControllerAnimated:YES];
}

在你的情况下

-(void)goToFirst:(id)sender
 {
        [self.navigationController popViewControllerAnimated:YES];
 }

答案 3 :(得分:0)

我上传了一个简单的应用程序到GitHub,我在评论中讨论了假导航栏,希望它有助于满足您的需求:https://github.com/yosihashamen/HelpersApps

要确保您必须始终保持“BaseViewController”处于活动状态。

答案 4 :(得分:0)

我的意思是这样的。

FirstViewController使用presentViewController代替pushUINavigationController添加新SecondViewController

-(void)goToSecond:(id)sender{
    SecondViewController *secondVC = [[SecondViewController alloc]init]; 
    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:secondVC];
    [self presentViewController:nav animated:YES completion:NIL];

}

SecondViewController中添加UIBarButtonItemNavigation bar

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStyleDone target:nil action:@selector(goToFirst:)];
self.navigationItem.backBarButtonItem = backButton;

并实施解雇方法。

-(void)goToFirst:(id)sender
 {
    [self dismissViewControllerAnimated:YES completion:NULL];
 }

答案 5 :(得分:0)

试用setViewControllers:animated:

这允许您在UINavigationController堆栈上显式设置视图控制器,就像您正在做的那样,它将自动处理导航动画,而无需您调用popViewControllerAnimated:

如果你有一个多视图旅程,你需要摆脱到目前为止已经显示的屏幕,但保持导航动画(例如,发布时的应用程序演示),或者如果你想轻松推送多个立即查看导航堆栈上的控制器。

Apple doc:https://developer.apple.com/library/ios/documentation/uikit/reference/UINavigationController_Class/Reference/Reference.html#jumpTo_21