0

I have been having some memory management issues and random crashes with my app. I have done a lot of work on it to try to clean up the code generally and have converted the project to ARC.

I now have a clear view on the problem - essentially the app does not release views so as a user moves through the app each view is reloaded and retained until finally the app crashes due to memory issues.

I have a UINavigationController. My app runs only in landscape left orientation. When i use

[window setRootViewController:viewController]; 

on load and then

[self.window addSubview:[finalViewController view]]; 

the new view is displayed in portrait - if i rotate it to landscape left with code when i load it in, then all kinds of other random issues come up.

If instead of addSubview i use

[self.viewController.view removeFromSuperview]; 
[self.window setRootViewController:finalViewController];
viewController = nil; 
self.viewController = nil; 
window.viewController = nil;

rotation is ok but views are not released and i have a memory issue with the app and it crashes eventually. Any thoughts would be awesome - appreciate i'm probably missing something fairly basic here. Thanks & happy holidays!

  • Before diving into your code, have you done an analyze? cmd+shift+b. If there are any issues try solving them! – Nico Dec 25 '12 at 12:53
  • Hi, thanks for getting back to me! I have no errors when i analyze the code - i've complete cleared all warnings to make sure there was nothing there that could be causing a problem - any thoughts on how to fix would be amazing! – user1837078 Dec 25 '12 at 17:12

1 Answers1

2

How are you loading new views in your app? If you are using a UINavigationController, your AppDelegate should start something like this:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    RootViewController* rootController = [[RootViewController alloc] init];
    UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController:rootController];
    [self.window setRootViewController:navController];

    [self.window makeKeyAndVisible];

    return YES;
}

To load another view(say from a button press) you will do something like this from within the root view:

SecondViewController *secondView = [SecondViewController alloc] init];
[self.navigationController pushViewController:secondView animated:YES];

This will make the UINavigationController responsible for memory management of your views.

As for rotation, that is handled by giving each of your ViewControllers this method:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    if(interfaceOrientation == UIInterfaceOrientationLandscapeLeft) return YES;
    return NO;
}

Aslong as you are using the UINavigationController the way it is meant to be used, you should not have any non-releasing views. You should read into the UINavigationController: http://developer.apple.com/library/ios/#documentation/uikit/reference/UINavigationController_Class/Reference/Reference.html

Another possibility is that the childviews of your view controllers have strong references to their parent view/controller. This will stop a parent viewcontroller from deallocating due to it giving its child a retain count of 1 and the child giving the parent a retain count of 1 as well. Here is a SO post with information on strong & weak references: Objective-C declared @property attributes (nonatomic, copy, strong, weak)

Community
  • 1
  • 1
PPierson
  • 410
  • 3
  • 18
  • Hi, thanks for the response - really appreciated! I've played around with property attributes without any luck & also looked at using SecondViewController *secondView = [SecondViewController alloc] init]; [self.navigationController pushViewController:secondView animated:YES]; but nothing happens when a button is pressed.I'm thinking I should create a new project - do you have a recommendation on the project type i should choose? I'm using version 4.5.2 Thanks :) – user1837078 Dec 28 '12 at 12:57
  • There shouldn't be any need to setup a new project. Did you create an IBAction for your button and insert the `pushViewController:` code in there? Are you sure you have the view hierarchy for using a UINavigationController correct? – PPierson Dec 28 '12 at 15:10
  • It sounds like you don't have your navigation implemented correctly. You should read deeper into using the UINavigationController. Here is a simple tutorial to get you started: [link](http://www.simplecode.me/2011/09/04/an-introduction-to-uinavigationcontroller/) – PPierson Dec 28 '12 at 15:27
  • Cool, thank you! Will check it out now & let you know how i get on :) – user1837078 Dec 28 '12 at 15:45
  • Thanks for all your suggestions - have learnt a lot :) In the end I reimplemented the UiNavigationController as you suggested. It worked well but i ran into some separate issues around switching views and random animation of elements. I also found i had the same issue with views being kept live. To get around the animation issue i switched back to my previous code & finally got the views to unload as i needed them to using [viewController viewDidUnload]; - very happy to have final fixed this - thanks again for your help :) – user1837078 Dec 30 '12 at 02:17
  • You may want to figure out another way to handle this. viewDidUnload is depreciated in iOS6 and does not get called anymore. You could put that code in viewWillDisappear, but this will also be called when views are pushed onto the navigation stack. – PPierson Dec 31 '12 at 00:26