【问题标题】:UIAlertView crash issue on another view controller另一个视图控制器上的 UIAlertView 崩溃问题
【发布时间】:2014-05-07 05:28:55
【问题描述】:

我有 2 个视图控制器,ViewController 1(VC1) 和 2(VC2)。在 VC2 中,我有一个后退和完成按钮。单击后退按钮时,它直接转到 VC1,完成后它会进行 api 调用,当它得到响应时,它会显示一个警报视图,然后单击确定会返回 VC1。现在,当我进行 api 调用时,加载栏会出现并在我得到响应时消失并显示AlertView。但是,如果在加载消失的那几分之一秒内,如果我单击返回并且视图更改为 VC1 将弹出AlertView,则警报会出现在 VC1 上并导致崩溃。

这是一种罕见的情况,因为没有用户会故意尝试它,但我想知道是否可以在不禁用后退按钮的情况下管理崩溃。我认为可能还有其他情况,例如我们正在进行异步调用,如果允许用户在等待响应时使用 UI,以及如果应该在一个 ViewController 上显示的任何错误警报出现在另一个可能导致崩溃,因为警报所指的委托是前一个视图控制器的委托。那么有什么办法可以有效地处理这种崩溃呢?

//Alert View sample
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[[message objectAtIndex:1] capitalizedString] message:[message objectAtIndex:0] delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil] ;
[alert setTag:701];
[alert show];

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if ([alertView tag] == 701)
        if (buttonIndex == 0)
        {
            [self.navigationController popViewControllerAnimated:YES];
        }


}

【问题讨论】:

  • 你能粘贴整个崩溃日志吗?
  • 崩溃是在点击确定后发生还是只是在出现警报时发生?
  • 我认为当警报打开然后当前视图控制器离开到另一个视图控制器并且警报仍然出现并且当他/她点击警报按钮时弹出视图控制器代码运行并崩溃时出现问题。
  • 出现警报,点击确定会导致它崩溃,因为委托设置为 self 应该在 VC2 上显示,而在 VC1 中显示。
  • 您的代码是否启用了 ARC?

标签: ios objective-c uialertview uialertviewdelegate


【解决方案1】:

解决此问题的正确方法是使用实​​例变量来保持对警报视图的引用。

这个实例变量应该在alertView:didDismissWithButtonIndex:委托方法中设置为nil

在视图控制器的dealloc 方法中,如果实例变量仍然设置,则调用dismissWithClickedButtonIndex:animated:

假设_alertView 是实例变量。

创建警报:

_alertView = [[UIAlertView alloc] initWithTitle:[[message objectAtIndex:1] capitalizedString] message:[message objectAtIndex:0] delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil] ;
[_alertView setTag:701];
[_alertView show];

更新您现有的alertView:clickedButtonAtIndex: 方法:

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    if ([alertView tag] == 701) {
         _alertView.delegate = nil;            
         _alertView = nil;
        if (buttonIndex == 0) {
            [self.navigationController popViewControllerAnimated:YES];
        }
    }
}

添加:

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
    _alertView = nil;
}

添加:

- (void)dealloc {
    if (_alertView) {
        _alertView.delegate = nil;
        [_alertView dismissWithClickedButtonIndex:_alertView.cancelButtonIndex animated:NO];
        _alertView = nil;
    }
}

【讨论】:

  • 这可以解决问题,但会导致正常流程崩溃,即当我单击完成并单击确定时,警报会返回然后崩溃。
  • 你对clickedButtonAtIndex:方法进行了我展示的更改吗?
  • 您可能还需要将_alertView.delegate = nil; 行添加到您的clickedButtonAtIndex: 方法中(就在调用_alertView = nil; 之前)。
  • 是的,我复制粘贴了您的代码。我尝试了dealloc中的断点,_alertView为nil,它没有进入,但仍然崩溃并出现EXC_BAD_ACCESS,注释dealloc代码工作正常。
  • 这就是我声明 alertView 接口 ViewController () {UIAlertView * _alertView;} end implementation ViewController ....
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-04
  • 1970-01-01
相关资源
最近更新 更多