views:

110

answers:

2

I'm getting an EXC_BAD_ACCESS after calling dismissModalViewControllerAnimated on my view controller. My project is based on the table view starter project, and RootViewController creates a view like this:

GobanVC *vc = [[GobanVC alloc] initWithNibName:@"GobanVC" bundle:[NSBundle mainBundle] coll:c];
[self.navigationController pushViewController:vc animated:YES];
[vc release];

In GobanVC.m, I'm handling a button to dismiss the view:

- (IBAction) onDone:(id) sender;
{
    [self.navigationController popViewControllerAnimated:YES];
}

For some reason the GobanVC object is getting over-released. I ran the allocation instrument, and I can see the reference count get set to 1 when I call alloc, then UIKit calls retain/release a bunch of times, and then my release above is handled. After that, none of the retain or releases are from my code, and after popViewControllerAnimated, the count becomes -1 eventually.

If I take the release above out, things seem to work okay, so it seems the count is off by exactly one somewhere.

Any ideas?

A: 

Maybe there is something wrong with GobanVC. Do you have the implementation for it?

Because if there is a retain for every release made by UIKit (there should be). And you say that your calls are balanced as well (one alloc and one release).

Then it means that in the implementation of GobanVC there must be something wrong.

Florin
A: 

Let's count the retains:

  1. Alloc makes it 1.
  2. Release makes it 0.

So, what comes out of the stack when you call pop will have retain counter equal to 0, which is NOT what you want. If you either remove release or keep it and assign "vc" to an instance variable defined as "retain" property, you will be fine.

From the code you provided I can see the following:

  1. Root controller creates an instance of GobanVC. The GobanVC's retain count is 1.

  2. Root controllers pushes GobanVC instance to the navigation stack. I am not sure if push increases the retain count. Most probably yes. Then the retain count of GobanVC instance becomes 2.

  3. You release the GobanVC instance, setting its counter to 1.

  4. Your button handler resides in GobanVC (not in the Root controller). So, GobanVC pops ITSELF from the stack with retain count 0 (because if push increases the counter, pop will decrease it). This IS a problem.

spbfox
Your assumption is correct: pushing a view controller will send it a `retain` message, and popping will send it a `release`. But I don't think it's a problem if the retain count reaches zero in `onDone`. The `popViewControllerAnimated:` message will be sent, the function will exit, and at that point the view controller doesn't need to be around anymore.
Frank Schmitt
Maybe yes, maybe no. Depends on what happens before and after and how underlying object management works. Do you know these details? I do not. At least I would not even try creating suicidal conditions from inside of an object. In my experience this kind of floating uncertainty (survive-or-die before I am done?) is the type of errors that extremely difficult to catch and that can randomly strike at any time.
spbfox