presentModalViewController无法正常工作

时间:2010-07-11 22:30:48

标签: iphone objective-c cocoa-touch uikit uiviewcontroller

我有3个观点。

我想做以下事情:

A presents B modally
A dismisses B
A presents C modally

我设置了一个委托模式,其中A是B的委托。这就是我在B中提出和解雇的方式:

[delegate dismissB]; //this is just [self dismissModalViewControllerAnimated:NO]
[delegate presentC]; //this is just [self presentModalViewController:c animated:NO];

由于某些原因,当我执行此代码而没有调试器结果时,我的应用程序崩溃了(我有NSZombieEnabled)。

当我发表评论[delegate presentC]时,该应用会正确解散B. 当我评论[delegate dismissB]时,即使该行已执行,该应用也不执行任何操作。我不确定原因?

更新 这是A

中的代码
-(void)showARView{
    [self dismissModalViewControllerAnimated:NO];

    ARViewController* arViewController = [[[ARViewController alloc] initWithNibName:@"ARViewController" bundle:nil]autorelease];
    UINavigationController *arNavController = [[UINavigationController alloc] initWithRootViewController:arViewController];

    LeaderBoardTableViewController* lbViewController = [[[LeaderBoardTableViewController alloc] initWithNibName:@"LeaderBoardTableViewController" bundle:nil]autorelease];
    lbViewController.title = @"Leaderboard";    
    UINavigationController *lbNavController = [[UINavigationController alloc] initWithRootViewController:lbViewController];

    arTabBarController = [[UITabBarController alloc] init];//initWithNibName:nil bundle:nil];
    arTabBarController.delegate = self;
    arTabBarController.viewControllers = [NSArray arrayWithObjects:arNavController, lbNavController, nil];
    arTabBarController.selectedViewController = arNavController;

    [arNavController release];
    [lbNavController release];

    [self presentModalViewController:arTabBarController animated:NO];
}

这是B

中的代码
[delegate showARView];

1 个答案:

答案 0 :(得分:0)

当你调用dismissB时,委托会解散viewcontroller。在正常情况下(如果你不在其他地方保留它),这会导致viewcontroller被同步释放。然后你试图访问委托实例变量,但为此,代码需要一个理智的(隐藏的)自我指针,它被解除分配。我不确定NSZombie在这种情况下是否可以提供帮助。通过在[[self retain] autorelease];之前插入[delegate dismissB];,您可以轻松找出导致崩溃的原因。然而,这是一个黑客而不是修复。你有设计问题。

这不是代表们的使用方式。 B呈现一些用户界面并接收一些用户交互。然后它应告诉A通过委托消息发生了什么,例如。 bWasCanceled或bFinished。在您的案例A中,代表有责任决定下一步该做什么。因此,在您的情况下,代理人可能决定解雇B而代之以C.或代码:

// Inside A
- (void)controllerB:(UIViewController*)ctl didFinishWithResult:(id)something {
    [self dismissModalViewControllerAnimated:NO];
    // Instantiate and initialize c
    [self presentModalViewController:c animated:NO];
}

// Inside B
[delegate controllerB:self didFinishWithResult:@"OK"];

如果我完全误解了你的代码,那里的一切都很好,我还有另一个建议。在同一轮runloop中解雇并呈现模态视图控制器时,我看到了一些奇怪的问题。您可以尝试[delegate performSelector:@selector(presentC) withObject:nil afterDelay:0.0];,看看是否有帮助。