【问题标题】:UIAlertView in ARC appARC 应用程序中的 UIAlertView
【发布时间】:2012-04-15 02:41:03
【问题描述】:

我有一个带有一个按钮的 iphone 示例应用程序。点击它会调用代码:

UIAlertView *alert = [[UIAlertView alloc]
                          initWithTitle:@"test"
                          message:@"test"
                          delegate:self
                          cancelButtonTitle:@"Ok"
                          otherButtonTitles: nil];
[alert show];

应用已启用 ARC。

问题是,如果我在警报中单击“确定”按钮,应用程序会因 EXC_BAD_ADDRESS 而崩溃 - 可能是因为警报已被 arc 删除。

有什么推荐的方法来解决这个问题?不向视图控制器添加属性

谢谢

【问题讨论】:

  • 使用僵尸工具找出崩溃发生的位置。
  • 您在委托方法中实际做了什么,崩溃的确切位置在哪里?

标签: iphone automatic-ref-counting


【解决方案1】:

我的猜测是你没有实现 UIAlertViewDelegate 方法或者 self 已经超出范围。

如果您不关心在有人关闭警报框时收到警报,请将代理更改为 nil。 例如

UIAlertView *alert = [[UIAlertView alloc]
                          initWithTitle:@"test"
                          message:@"test"
                          delegate:nil
                          cancelButtonTitle:@"Ok"
                          otherButtonTitles: nil];
[alert show];

【讨论】:

    【解决方案2】:

    UIAlertView 的委托属性被声明为弱引用(由 assign 关键字指示)。这意味着 ARC 不会增加保留计数,您将需要保留对委托对象的引用(无论是自身还是单独的对象)。此引用应在 UIAlertView 的整个生命周期内保持。

    @property(nonatomic,assign) id /*<UIAlertViewDelegate>*/ delegate;    // weak reference
    

    我认为这样做的原因是为了防止循环和无法释放,因为在常见情况下,创建 UIAlertView 的对象将保留对它的引用,并且它是委托,因此关闭循环并防止释放。

    这可能是代表的常见模式,但直到遇到完全相同的问题时我才意识到。我在启用僵尸检测的模拟器中运行,它清楚地指示了引用计数,我看到它没有被 UIAlertView 保留。那是我检查头文件的时候。

    这个问题的答案提供了一些关于系统类的委托和assign关键字的额外信息。 iPhone ARC Release Notes - dealloc on system classes delegates?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-03
      • 1970-01-01
      • 2012-03-25
      • 2012-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多