Objective-C / iPhone Memory Management

In my iPhone application, I have a "statistics" view that is displayed by the following method: the method itself is called when the user touches the button. This method is inUINavigationController

- (void) showStatsView {
    StatsViewController *statsViewController = [[StatsViewController alloc] initWithNibName:@"Stats" bundle:[NSBundle mainBundle]];
    [self pushViewController:statsViewController animated:YES];
    [statsViewController release]; //                       (1)
}

      

In the very presentation of statistics NSDictionary

, " statsDict

" is used. It is declared as a property with the following parameters: (non-atomic, persist).

In my StatsViewController, the method viewDidLoad

creates an instance NSDictionary

like this:

MyAppDelegate *appDelegate= (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
stats = [[NSDictionary alloc] initWithContentsOfFile:[appDelegate statsFilePath]];

      

My dealloc method for StatsViewController looks like this:

 - (void)dealloc {

    /* 
    dealloc'ing other stuff here which is irrelavent
    */
    [statsDict release]; //                 (2)
    [super dealloc];
}

      

My problem comes up if I try to reload the statistics view after it has been shown once, that is - I click a button that triggers showStatsView to start, which loads the statistics view (for the first time), and everything is currently fine.

If I then click the button in the statistics window to return to the main menu (which is done by calling the method it uses [self popToViewController:MainMenuViewController];

), from here, if I click the button that loads the statistics view again (a second time), my application crashes with EXC_BAD_ACCESS

.

If I remove the line marked (1) in showStatsView then it works fine as if I remove the line marked (2) in dealloc. However, from what I've read, I have to post the statsDict since I have selected it, also I have to post the statsViewController since I have selected this too. However, if I do both, it works! What should I do?

Am I missing some step in my understanding of objective-c memory management?

+2


source to share


2 answers


Your understanding of the contract seems to be correct (if you mean "statsDict =" where you say "stats =").

So the problem is somewhere else, probably in breach of contract somewhere else.



I would suggest you turn on memory debugging with environment variables NSZombieEnabled

and NSAutoreleaseFreedObjectCheckEnabled

and see if it tells you which objerct is already released.

+2


source


The reason your application doesn't crash when you delete (1) or (2) is because both of them have the effect of intentionally leaking the dictionary (at point 2 by leaking the dictionary and at point 1 by leaking the owner dictionary. so -dealloc is never called.) Obviously you don't want to do this. Your understanding of the contract is correct, but I think you don't understand how your object is initialized.

You haven't reproduced your -init code here, but I guess the problem is that -viewDidLoad only gets one time when the view is unpacked. Therefore, on subsequent instantiations of statsViewController, the dictionary is not allocated.



If you move the row selection and insert the NSDictionary from -viewDidLoad into the -init method of statsViewController, everything works fine unless you intentionally leak objects. -init will be called every time you create a new statsViewController. If you don't have a -init method, create one (and don't forget to call [super init]).

Good luck.

+1


source







All Articles