views:

532

answers:

4

Hi all

Here's the scenario: On my iPhone app (OS 3.1.2), I've got "view 1" which navigates to "view 2" using a pushViewController call. Then, on "view 2", the user can optionally call "view 3", which is displayed using presentModalViewController and an animation (flip horizontal transition). I can switch view 1 <-> view 2 back and forth without any problem. But if I do view 1 -> view 2 -> view 3, I can get back to view 2 (with the appropriate dismissModalViewControllerAnimated call in view 3) ; once in view 2, getting back to view 1 makes the application crash with the "standard" objc_msgSend error.

Here's how I navigate from view 1 to view 2:

NewsArticleController *articleViewController = [[NewsArticleController alloc] initWithNibName:@"NewsView" bundle:nil news:f1Data];
articleViewController.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:articleViewController animated:YES];
[articleViewController release];

Here's how I navigate from view 2 to view 3:

addFeedController = [[AddFeedViewController alloc] initWithNibName:@"AddFeedView" bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:addFeedController];
[addFeedController release];
navigationController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[[self navigationController] presentModalViewController:navigationController animated:YES];
[navigationController release];

Here's how view 3 dismisses to get back to view 2:

- (IBAction)cancel
{
    [self dismissModalViewControllerAnimated:YES];
}

And finally, the stack trace:

#0  0x96a8aedb in objc_msgSend
#1  0x04859550 in ??
#2  0x01c26908 in CFRelease
#3  0x01c49869 in __CFDictionaryDeallocate
#4  0x01c26a41 in _CFRelease
#5  0x00043cf5 in NSPopAutoreleasePool
#6  0x035f7858 in run_animation_callbacks
#7  0x035f75f5 in CA::timer_callback
#8  0x01c67ac0 in CFRunLoopRunSpecific
#9  0x01c66c48 in CFRunLoopRunInMode
#10 0x0245378d in GSEventRunModal
#11 0x02453852 in GSEventRun
#12 0x002d3003 in UIApplicationMain
#13 0x000023b0 in main at main.m:5

Maybe I'm blind and don't see the error here, but I'm really stuck. Please help!

A: 

For your -cancel action method, shouldn't that be:

[[self navigationController] dismissModalViewControllerAnimated:YES];
Alex Reynolds
When doing this, the code compiles and runs fine, but the "Cancel" button doesn't do anything anymore (nothing is dismissed). It must be something else, but thanks anyway.
Romain
That's odd. Perhaps look into NSZombie to see if you have overreleased or released an object early.
Alex Reynolds
A: 

The code you posted is fine.

The problem occurs because an object is getting prematurely deallocated. It's probably related to some code in your 3rd view.

You can use NSZombie to help you find the problem.

Darren
Thanks for pointing me to zombieland! By using this technique I managed to find out that stupid bug.FYI, you can see in the 2nd block of code I posted that I was doing "addFeedController = ...", meaning that variable was defined as an instance variable.Of course, I was releasing that variable in my dealloc. But actually, I just can't remember why I ever needed this variable to be put in the instance. A local variable with a local release was enough and this stopped my app from crashing.Thanks again!
Romain
A: 

When navigating from view 2 to view 3, your creating a new UIViewController. I cant really see why you'd do this. To navigate to view 3, you could just do:

addFeedController = [[AddFeedViewController alloc] initWithNibName:@"AddFeedView" bundle:nil];
[self.navigationController presentModalViewController:addFeedController animated:YES];
[addFeedController release];
Mez
You're right, thanks, I changed my code in that way.It doesn't keep my app from crashing however, so this isn't the reason.
Romain
A: 

In the 2nd block of code I posted, I was doing:

addFeedController = [[AddFeedViewController alloc] initWithNibName:@"AddFeedView" bundle:nil];
...

As you might infer, addFeedController was defined as an instance variable. Of course, I was nicely releasing that variable in my dealloc. But actually, I just can't remember why I ever needed this variable to be put in the instance. This precisely caused that variable to be released twice if ever allocated once. A local variable with a local release was enough and this stopped my app from crashing.

NSZombie helped me catch this bug... Thanks to you all!

Romain