0

这个问题只发生在 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 出现问题。

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

我发现视图控制器正在被释放,但前提是该视图控制器显示 UIAlertView。究竟是什么会导致视图控制器因为它将自己设置为 UIAlertView 的委托然后显示它而被解除分配?

我的应用程序委托有strong对视图控制器的引用,所以我绝对没有理由看到视图控制器被释放。


编辑2:我发现在启动期间我的主视图控制器被实例化了两次。第一个是创建 UIAlertView 的那个,那个正在被释放。第二个是我之后能够与之交互的那个,它让我认为视图控制器仍然存在并且可以操作。

但是,我无法弄清楚我的视图控制器在哪里或为什么会被创建两次。我没有任何用于视图控制器的 alloc/init 语句。它只存在于 MainWindow_iPhone.xib 中。

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


编辑3:我已经“解决”了这个问题,但我不明白为什么会发生这种情况。也许你可以帮助我理解。

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

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

4

2 回答 2

1

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

UIAlertView 委托分配非弱引用。当委托被释放时,它不会自动设置为 nil。这就是您的代码崩溃的原因。

于 2013-09-11T19:46:51.870 回答
0

我修复了这个问题,评论这个方法(或删除它)。

- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
{
    NSLog(@"se apreto cancel");
}

正如 James Wang 所说,在 clickedButtonAtIndex 之后调用了 didDismissWithButtonIndex,所以我对其进行了评论以避免崩溃。

于 2013-11-28T01:39:48.330 回答