3

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

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

应用程序已启用 ARC。

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

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

谢谢

4

2 回答 2

5

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

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

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

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

这个问题的答案提供了一些关于系统类的委托和assign关键字的附加信息。 iPhone ARC 发行说明 - 在系统类代表上解除分配?

于 2012-07-02T23:59:37.293 回答
5

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

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

UIAlertView *alert = [[UIAlertView alloc]
                          initWithTitle:@"test"
                          message:@"test"
                          delegate:nil
                          cancelButtonTitle:@"Ok"
                          otherButtonTitles: nil];
[alert show];
于 2012-04-15T05:55:32.193 回答