这个问题只发生在 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 中视图控制器会被创建两次?