views:

297

answers:

5

Hi, I'm developing an iPhone app, I'm trying to push a view into the navigation controller, which I've done many times before, however, I'm having some issues with this particular app. I have a table view, and when the user selects one row the new view is pushed into the controller:

DataWrapper *row=[[self.rows objectAtIndex:[indexPath section]] objectAtIndex:[indexPath row]];
DataViewController *nextController=[[DataViewController alloc] initWithNibName:@"Data" bundle:[NSBundle mainBundle]];
[nextController setInfo:row];
[nextController setRow:[indexPath row]];
[nextController setParent:self];
[self.navigationController pushViewController:nextController animated:YES];
[nextController release];

and it goes fine, until the user taps the back button, I get an exception, and used NSZombieEnabled and get this:

-[DataViewController respondsToSelector:]: message sent to deallocated instance 0x4637a00

So i tried to remove the [nextController release] and in fact it worked, but WHY???? I allocated nextController, so I'm supposed to release it, right?? I don't feel right releasing this app if there's something like this, I feel like it's going to fail. Please let me know your thoughts.

A: 

I would guess that [self.navigationController] is returning nil, because if it weren't nil, it would be retaining your object. Since your object is not getting retained, it would appear that there is no object that's trying to retain it, indicating that the navigationController property is empty.

Dave DeLong
That doesn't explain why it works though... if that was being called on `nil`, the screen would never show up.
igul222
A: 

Is it possible that your navigation controller is somehow being deallocated, resulting in the view controllers also getting released? You could maybe test it by retaining the nav controller just before pushing nextController.

codelogic
A: 

For debugging purposes, I would override -dealloc in your DataViewController class, and set a breakpoint on it.

NSResponder
+1  A: 

Your nextController isn't being retained by navigation controller. If you release it then because there is only one init/release pair, the object is deallocated. Later when the navigationController attempts to send messages to it, you get the error you see.

This is also why remove [nextController release] fixes the problem.

You are right in that if you allocated, you should free it. But the caveat is only after your application is done with it, not before.

Some objects will stay allocated for nearly the lifetime of the application, so don't feel too bad.

freespace
I think the clean way would be to allocate the `DataViewController` in the `- viewDidLoad` method and then deallocate it again in the `- viewDidUnload` method.
frenetisch applaudierend
I see, I thougt that when you use pushViewController the NavigationController takes ownership of the object. I'll try to alloc the controller in viewDidLoad.
Leg10n
@Leg10n: unless the documentation specifically says a method will `retain` an object, or an property has setters which `retain`, never assume another object will take ownership.
freespace
A: 

but it seems to work for something like:

DetailViewController *controller = [[DetailViewController alloc] initWithNibName:@"SomeView" bundle:nil]; 

controller.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController: controller animated:NO];

[controller release];

so, why is it not working for pushViewController ?

iPortable