UIViewController not being released from memory wh

2019-08-30 22:34发布

I have a UINavigationController and I'm trying to release from memory every UIViewController once another one is on top of the stack. I assign the viewControllers property of the UINavigationController to the new UIViewController and then pop into it. This way I always have just one UIViewController in stack. However, the memory keeps adding up every time I create a new UIViewController. Dealloc is called, but the memory usage remains the same.

You can download the example project HERE

FirstViewController.h

#import "SecondViewController.h"

@interface FirstViewController : UIViewController

-(IBAction)goToSecond:(id)sender;

@end

FirstViewController.m

#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.h

#import "FirstViewController.h"

@interface SecondViewController : UIViewController

-(IBAction)goToFirst:(id)sender;

@end

SecondViewController.m

#import "SecondViewController.h"

@interface SecondViewController ()

@end

@implementation SecondViewController

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

}

-(void)goToFirst:(id)sender{

    FirstViewController *firstVC = [[FirstViewController alloc]init];
    [self.navigationController setViewControllers:@[firstVC]];
    [self.navigationController popViewControllerAnimated:NO];

}

-(void)dealloc{

    NSLog(@"SecondVC dealloc");
}

@end

6条回答
Animai°情兽
2楼-- · 2019-08-30 23:20

I'm not sure about the benefit of a uinavigationcontroller but anyway you could add this snippet on your .m of your uiviewcontrollers

-(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;
    }
}

And instead of

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

you can set

[self.navigationController pushViewController:[[FirstViewController alloc] init] animated:NO];
查看更多
神经病院院长
3楼-- · 2019-08-30 23:22

What I mean is something like this.

In your FirstViewController use presentViewController instead of push adding a new UINavigationController to the SecondViewController

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

}

In the SecondViewController add an UIBarButtonItem to the Navigation bar

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

And implement dismiss method.

-(void)goToFirst:(id)sender
 {
    [self dismissViewControllerAnimated:YES completion:NULL];
 }
查看更多
淡お忘
4楼-- · 2019-08-30 23:32

I uploaded a simple app to GitHub, with the fake navigation bar that i was talking about in my comment, hope it helps for your needs: https://github.com/yosihashamen/HelpersApps

Be ware that you must keep on "BaseViewController" alive at all times.

查看更多
The star\"
5楼-- · 2019-08-30 23:38

You are using pop to go further, but you need to use push if you want to go to the next ViewController.

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

And in the SecondViewController to go back to your FirstViewController you should use pop

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

In your case

-(void)goToFirst:(id)sender
 {
        [self.navigationController popViewControllerAnimated:YES];
 }
查看更多
ゆ 、 Hurt°
6楼-- · 2019-08-30 23:40

Navigation controller should not be used as you intended. You should call pushViewController and popViewController for present/dismiss your viewControllers. If you have memory issues, try to release memory in didReceiveMemoryWarning callback

查看更多
走好不送
7楼-- · 2019-08-30 23:41

Try out setViewControllers:animated:

This allows you to explicitly set the view controllers on the UINavigationController stack, like you are doing, and it will automatically handle the navigation animation without you having to call popViewControllerAnimated:

This is useful if you have a multi-view journey where you need to get rid of the screens that have been shown so far but maintain the navigation animation (eg. app demo on launch) or if you want to easily push multiple view controllers on the navigation stack at once.

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

查看更多
登录 后发表回答