Reputation:
In my iPhone app, I have a "statistics" view that is displayed by the following method - the method itself is called when the user touches a button. This method is in a UINavigationController
- (void) showStatsView {
StatsViewController *statsViewController = [[StatsViewController alloc] initWithNibName:@"Stats" bundle:[NSBundle mainBundle]];
[self pushViewController:statsViewController animated:YES];
[statsViewController release]; // (1)
}
In the statistics view itself, an NSDictionary
, "statsDict
" is used. It's declared as a property with the following options: (nonatomic, retain).
In my StatsViewController, the viewDidLoad
method creates the instance of the NSDictionary
like so:
MyAppDelegate *appDelegate= (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
stats = [[NSDictionary alloc] initWithContentsOfFile:[appDelegate statsFilePath]];
My dealloc method for StatsViewController looks like:
- (void)dealloc {
/*
dealloc'ing other stuff here which is irrelavent
*/
[statsDict release]; // (2)
[super dealloc];
}
My problem occurs if I attempt to reload the Statistics view after it's been shown once, that is - I press the button which causes showStatsView to fire, which loads the Statistics view (for the first time), and all is currently fine.
If I then press a button on the Statistics View to return back to the main menu (which is done via a call to a method which uses [self popToViewController:MainMenuViewController];
) - from here, if I press the button which loads the Statistics view again (for the second time), my app crashes with EXC_BAD_ACCESS
.
If I remove the line marked (1) in showStatsView, then it works fine, as it does if I remove the line marked (2) in dealloc. However, from what I've read, I should release statsDict, as I allocated it, likewise, I should release statsViewController, as I allocated that too. However, if I do both - it crashes! What should I do?
Have I missed some step in my understanding of objective-c memory management?
Upvotes: 2
Views: 483
Reputation: 17811
Your understanding of the contract appears correct (assuming you mean "statsDict =" where you say "stats =").
So the problem is somewhere else, likely breaking the contract somewhere else.
I would suggest you turn on some memory debugging with environment variables NSZombieEnabled
and NSAutoreleaseFreedObjectCheckEnabled
and see if it tells you which objerct is being over released.
Upvotes: 2
Reputation: 1378
The reason your app doesn't crash when you remove (1) or (2) is that both of those have the effect of intentionally leaking the dictionary (at point 2 by leaking the dictionary, and at point 1 by leaking the dictionary's owner, so -dealloc never gets called.) Obviously that's not something you want to do. Your understanding of the contract is correct, but I think you are misunderstanding how your object is being initialized.
You didn't reproduce your -init code here, but at a guess, I think the issue here is that -viewDidLoad only gets called once when the view is unarchived. So on subsequent creations of the statsViewController, the dictionary isn't allocated.
If you move the line allocating and initting the NSDictionary from -viewDidLoad into the -init method of statsViewController, everything will work fine without your having to intentionally leak objects. -init is going to be called every time you create a new statsViewController. If you don't have an -init method, create one (and don't forget to call [super init]).
Best of luck.
Upvotes: 1