组合pushViewController和presentModalViewController时,iPhone应用程序崩溃与objc_msgSend

时间:2009-12-18 21:51:31

标签: iphone objective-c

以下是该方案: 在我的iPhone应用程序(OS 3.1.2)上,我有“view 1”,它使用pushViewController调用导航到“view 2”。然后,在“视图2”上,用户可以选择性地调用“视图3”,其使用presentModalViewController和动画(翻转水平过渡)显示。 我可以切换视图1< - >查看2来回没有任何问题。 但如果我查看1 - >视图2 - >查看3,我可以返回查看2(在视图3中使用相应的dismissModalViewControllerAnimated调用);一旦进入视图2,返回视图1会使应用程序崩溃,并出现“标准”objc_msgSend错误。

以下是我从视图1导航到视图2的方式:

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

以下是我从视图2导航到视图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];

以下是视图3如何解散以回到视图2:

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

最后,堆栈跟踪:

#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

也许我是盲目的,并没有在这里看到错误,但我真的被卡住了。请帮忙!

4 个答案:

答案 0 :(得分:1)

您发布的代码很好。

出现此问题是因为对象过早地被释放。它可能与你的第三个视图中的一些代码有关。

您可以使用NSZombie来帮助您找到问题。

答案 1 :(得分:0)

对于您的-cancel操作方法,不应该是:

[[self navigationController] dismissModalViewControllerAnimated:YES];

答案 2 :(得分:0)

从视图2导航到视图3时,您将创建一个新的UIViewController。我真的不明白你为什么要这样做。 要导航到视图3,您可以这样做:

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

答案 3 :(得分:0)

在我发布的第二段代码中,我正在做:

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

正如您可能推断的那样,addFeedController被定义为实例变量。当然,我很好地在我的dealloc中发布了这个变量。但实际上,我只是不记得为什么我需要将这个变量放在实例中。这恰好导致该变量在被分配一次后被释放两次。 具有本地版本的本地变量就足够了,这阻止了我的应用程序崩溃。

NSZombie帮助我抓住了这个错误......谢谢大家!