alertView:didDismissWithButtonIndex:发送到解除分配的实例的消息

时间:2012-10-30 19:14:12

标签: ios uialertview ios4

问题只发生在iOS4.3上。我正在使用ARC,而我的Base SDK是iOS6。

在我的视图控制器的-viewDidAppear中,我检查这是否是第一次启动应用程序,如果是,那么我创建并显示UIAlertView。我将UIAlertView分配给视图控制器上的strong属性,并将self设置为UIAlertView委托。

self.uiAlertView = [[UIAlertView alloc] initWithTitle:@"Welcome!"
                                              message:messageString 
                                             delegate:self
                                    cancelButtonTitle:@"OK"
                                    otherButtonTitles:@"View Tutorial Videos", @"Email Support", nil];

当我点按其中一个按钮时,应用程序崩溃,抱怨-alertView:didDismissWithButtonIndex:已发送到已取消分配的实例。委托是显示UIAlertView的视图控制器。

在应用程序的所有后续启动中,当未显示UIAlertView时没有问题。视图控制器肯定没有被释放。

如果我显示UIAlertView但是将委托设置为nil,那么没有问题,应用程序继续工作,所以很明显视图控制器还没有被释放,因为我可以继续使用它。

发生了什么事?这只会导致iOS4.3出现问题。

编辑:根据评论中的建议,我在不同的地方添加了一些日志消息。

我发现视图控制器正在被dealloc'd,但前提是该视图控制器显示UIAlertView。世界上的什么会导致视图控制器被释放,因为它将自己设置为UIAlertView的委托,然后显示它?

我的应用代理对视图控制器有一个strong引用,因此我绝对没有理由让视图控制器获得dealloc'd。


编辑2:我发现在启动期间我的主视图控制器正在实例化TWICE。第一个是创建UIAlertView的那个,并且正在进行dealloc'd。第二个是我之后能够与之交互的那个,这让我觉得视图控制器仍然存在且可操作。

然而,我无法弄清楚我的视图控制器将被创建两次的原因或原因。我没有视图控制器的任何alloc / init语句。它只存在于MainWindow_iPhone.xib中。

第一次在我的视图控制器上调用viewDidLoad时,上面的堆栈帧是[UIViewController视图]。在我的视图控制器的第二个实例上第二次调用viewDidLoad,上面的堆栈框架是[UINib instantiateWithOwner:options:]


编辑3:我已经“修复”了这个问题,但我不明白为什么会这样。也许你可以帮助我理解。

在我的MainWindow_iPhone.xib中,我创建了我的根视图控制器并将其分配给我的app委托上的IBOutlet。相反,我从xib中删除了视图控制器,并在-application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions中的代码中创建了它......问题就消失了。

为什么世界上会在xib中创建两次视图控制器?

2 个答案:

答案 0 :(得分:1)

我之前有这个问题。 alertView:didDismissWithButtonIndex:在alertView之后调用:clickedButtonAtIndex:。您最有可能通过执行[self.navigationController popViewControllerAnimated:YES]之类的操作来释放alertView中的视图控制器:clickedButtonAtIndex。

UIAlertView委托分配的不是弱引用。取消分配委托时,它不会自动设置为nil。这就是你的代码崩溃的原因。

答案 1 :(得分:0)

我修复了此问题,注释了此方法(或删除它)。

- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
{
    NSLog(@"se apreto cancel");
}
正如James Wang所说,在clickedButtonAtIndex之后调用didDismissWithButtonIndex,所以我对它进行了评论以避免崩溃。