views:

2075

answers:

3

So yeah, I'm a Java guy in this crazy iPhone world. When it comes to memory management I stiill don't have a very good idea of what I'm doing.

I have an app that uses a navigation controller, and when it's time to go on to the next view I have code that looks like this:

UIViewController *myController = [[MyViewController alloc] initWithNibName:@"MyView" 
                                                                    bundle:[NSBundle mainBundle];
[[self navigationController] pushViewController:myController animated:YES];

Now according to Apple's fundamental rule on memory management

You take ownership of an object if you create it using a method whose name begins with “alloc” or “new” or contains “copy” (for example, alloc, newObject, or mutableCopy), or if you send it a retain message. You are responsible for relinquishing ownership of objects you own using release or autorelease. Any other time you receive an object, you must not release it.

To me that means that I should be releasing myController, or giving it an autorelease message. But, whenever I try doing that my application winds up crashing as I push and pop views off of the stack.

This didn't smell right to me, but in running Instruments it claims that I don't have any memory leaks.

So I my question is

  1. Am I doing this right?
  2. Is the Navigation Controller taking ownership of MyViewController, explaining the lack of a memory leak?
  3. Should I assign myController to an instance variable in my root ViewController? In that case it would be marked retain and I would release in the root's dealloc method
+9  A: 

The problem is (most likely) you're releasing your viewController before the Navigation Controller has a chance to claim ownership. There are two ways around this:

  • -release your controller after pushing it to the Nav Controller
  • -autorelease your controller before pushing it. If you do this, the active NSAutoreleasePool (which you don't need to worry about) will take care of releasing your controller at a later time.
Ben Gottlieb
+2  A: 

@Ben Gottlieb why do you need to autorelease before pushing it? Retain count at object allocation is 1, autorelease before or after pushing doesn't affect the retain count, though generally autoreleasing as a matter of style is applied afer object alloc/init:

[[[object alloc] init] autorelease];

@bpapa,

2) When pushing, the navigation controller will retain the view controller. Later when this view is popped off the navigation controller stack, the navigation controller will release it.

3) Unless there's a explicit reason to hold onto that view no you should not assign it to an instance variable. In general you want your views to exist only as long as you need them.

dnolen
I was just contrasting the use of autorelease with release. You can autorelease before or after, it doesn't matter, but if you release, you MUST do it after.
Ben Gottlieb
A: 

I created a navigation controller with a root view controller in the initWithRootViewController method, once I'm done using the navigation controller, I try to release it and it gives me an error (crashes).

I don't know what is going on?

navigationcontroller initWithRootViewController:Xviewcontroller;

add the navigationcontroller's view to the window as a subview

how can i release it properly? (the navigation controller)