【问题标题】:How to prevent EXC_BAD_ACCESS on an object I don't know is released in iOS 9?如何防止我不知道在 iOS 9 中发布的对象上的 EXC_BAD_ACCESS?
【发布时间】:2016-01-22 01:16:10
【问题描述】:

我使用 NSURLConnection 下载文件,当用户点击返回时,我不一定知道连接是否已完成并已正确处理。所以我添加了以下检查,如果连接不为空,请取消它。

if (self.urlConnection){
    [self.urlConnection cancel];
}

这在 iOS 7/8 中有效,我从未收到过异常。但是现在在 iOS 9 中,当我检查连接是否存在(并且不存在)时,我得到了一个异常。这是上面的第一行,在我实际调用 url 之前。

我不明白为什么检查一个对象是否为 nil 会引发异常,如果确实如此 - 我怎么能期望防止这个异常。

在我调用它之前,是否有一种新方法可以确保对象存在并且尚未被释放?

编辑:这是属性的声明方式:

@property (nonatomic, assign) NSURLConnection *urlConnection;

如果对象实际上还没有被实例化,检查工作正常。只有当连接完成并变为 nil 时,然后我尝试检查检查是否为 nil 才会爆炸。这在早期的 iO​​S 版本上没有发生。

【问题讨论】:

  • (1) urlConnection 属性是如何声明的? (2) 你确定self 存在吗? (3) 你确定这发生在主线程上吗?
  • 什么异常/错误?请完整的错误文本。
  • 完整的错误是上面的EXC。 Xcode 不会发出其他消息,也不会显示其他任何消息。
  • 我在上面添加了声明。我确信 self 存在,它稍后在方法中使用并且不会失败。这是在按下按钮后发生的(并且在按下按钮后建立了连接)。唯一的多线程代码是连接,所以我没有做任何线程。
  • 尝试在此语句之前访问 self 的任何其他变量以检查 self 是否存在

标签: ios objective-c xcode ios9 exc-bad-access


【解决方案1】:

是的,有……使用弱引用。

__weak typeof(self) weakSelf = self;
...
..
.
[weakSelf.urlConnection cancel]

【讨论】:

  • 我使用的是弱引用。当我尝试检查弱引用是否为 nil 时,就会抛出错误。
  • 在您提供的代码中,不清楚“self”是弱的。虽然您正在检查“urlConnection”是否为非零,但如果 self 不再是有效内存,您将继续遇到问题。
  • Self 就是 self,我对此无能为力,它不是一个新变量,而是对象的 self 作用域(保留关键字)。除此之外,还有其他代码在该方法中引用 self 确实有效(始终,有和没有这一行,有和没有错误)。所以问题不在于自己。
  • 如果不了解更多(代码、描述等),这本质上就像在黑暗中扔飞镖,但是为了争论,如果你定义和使用 self 的弱引用会发生什么?无论如何,无论您实际找到什么作为解决方案,请将其发回此处以供所有人受益。
  • 我明白了,但确实没有更多相关信息。我将如何定义对自我的弱引用?下一行是 [self.property doSomething],它永远不会在 if (self.connection) 失败的地方失败。
【解决方案2】:

NSURLConnection 是一个对象,需要是一个strong 引用。 Assign 仅适用于原始值。如果你真的打算创建这个属性weak,那么使用这个模式来确保你的对象在使用它时不会超出范围:

//code that goes in some method
NSURLConnection* strongConnection = self.urlConnection;
if(strongConnection) {
    //code to do stuff with the url connection
    [strongConnection cancel];
}

我还敦促谨慎对待 weak 引用,特别是当您提到对象处理通知或观察更改时。弱对象被破坏并且通知或观察者没有被取消注册,我已经不止一次被咬了。

【讨论】:

  • 啊,在这种情况下我肯定错误地使用了assign,因为我没有意识到它是针对原语的。这可能是它的全部原因。我看不出重写会做什么,但也会尝试。我似乎没有遇到通知问题,但这也是一个很好的提示!
  • 我认为弱是问题所在。这个link 说“将assign for primatives - 就像weak 一样,只是它在释放时不会消除对象”会导致我的问题 - 它没有将它设置为nil,所以当我检查它是否为nil时我得到了一个错误。将报告,但这似乎是问题所在。奇怪它是如何工作的
猜你喜欢
  • 2022-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-09
  • 1970-01-01
相关资源
最近更新 更多