views:

35

answers:

2

Hello,

I am relatively new to Cocoa programming, and some aspects of memory managing are still troubling me.

In this case, I am creating a UINavigationController using the alloc message, and initialising it with a UIView controller. Then, I am presenting the view modaly by passing it to the presentModalViewController method. Below is the code:

- (void)tableView:(UITableView *)tableView 
accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"Tapped on disclosure button");
NewPropertyViewController *newProperty = [[NewPropertyViewController alloc] 
                                          initWithDictionary];
newProperty.editProperty = [fetchedResultsController objectAtIndexPath:indexPath];
UINavigationController *newPropertyNavigationController = [[UINavigationController 
                                          alloc] 
                                          initWithRootViewController:newProperty];
[newProperty setPropertyDelegate:self];
[self presentModalViewController:newPropertyNavigationController animated:YES];

[newProperty release];
[newPropertyNavigationController release];
}

According to the retain count rules, if I send the message "alloc" to a class, an instance of that class is returned with retain count 1, and I am responsible for releasing it. In the above code, I release the newPropertyNavigationController instance after passing it to the modalViewController and presenting it. When I dismiss the modal view, the app crashes.

If I comment out the last line, the app doesn't crash.

Why is this happening? Is the particular alloc/init message to the UINavigationController working differently to the way it works in other classes, ie. is it perhaps returning an autoreleased instance?

Thanks!

Peter

+2  A: 

You need to stop what you're doing and read through this. The rules for memory management are very simple and understandable. Let them be burnt into your head (doesn't take long). Then examine your code line by line in your trouble spots, and apis that get called into from your code. Tracing through your code this way while the rules are fresh in your head, will help you fix your memory problems, and maybe, just maybe, help you prevent from making them in the future.

jer
Thanks for the pointer Peter, it helped a lot to find the problem. See my reply to Acusete's comment.
futureshocked
+1  A: 

The way you create the modal view controller looks correct. Check the implementation of dealloc on your modal view controllers to see if the problem lies there.

If you are incorrectly deleting memory there it would explain why you only get the error when you release the modal view controller.

For reference I find the following use of autorelease much more readable and maintainable

NewPropertyViewController *newProperty = [[[NewPropertyViewController alloc] 
                                      initWithDictionary] autorelease];
newProperty.editProperty = [fetchedResultsController objectAtIndexPath:indexPath];
UINavigationController *newPropertyNavigationController = [[[UINavigationController 
                                      alloc]
                                      initWithRootViewController:newProperty] autorelease];
[newProperty setPropertyDelegate:self];
[self presentModalViewController:newPropertyNavigationController animated:YES];
Akusete
Don't autorelease the UINavigationController object before you initialize it. You should not send any message to an uninitialized object, except the message that initializes it. The `autorelease` message should come after the `initWithRootViewController:` message. (Editing error?)
Peter Hosey
@Peter Hosey: ahh, yes. typo fixed. Thanks
Akusete
Found the problem. As you suggested, I looked in the newProperty object, and found that in the dealloc method I was sending the dealloc message to the object's properties instead of the release message. It's an embarrassing mistake, but there it is.Thanks for your help, its appreciated.
futureshocked