【问题标题】:How to fix the bug where viewDidScroll is called when UIViewController is already gone?如何修复 UIViewController 已经消失时调用 viewDidScroll 的错误?
【发布时间】:2013-12-23 11:45:25
【问题描述】:

我经常得到 excbadaccess。非常罕见。但有时会发生。

我尝试了僵尸构建,我得到了这个:

*** -[BGDetailBusinessViewController scrollViewDidScroll:]: message sent to deallocated instance 0x189f09c0

我想这是由于以下原因而发生的

我在滚动时弹出一个 BGDetailBusinessViewController。

视图仍在滚动。

它在某处发送通知以调用它的委托,即 BGDetailBusinessViewController 对象。因为对委托的引用很弱,我想这是导致问题的原因。

现在,我该如何解决这个问题?

弱引用的工作方式是,如果对象被释放,它就会为零,对吧?

也许不是因为僵尸的缘故。但是,这意味着如果我使用僵尸构建构建,就会出现这个错误。

如果一个对象变成僵尸,所有对该对象的弱引用都会被取消吗?

无论如何,我想知道如何修复这个错误,因为我已经设法找到它。

有人说我应该在 dealloc 中将 delegate 设置为 nil。

Are all weak references nilled if we enable zombie object? 另有建议。当一个对象被释放时,所有弱引用,这样的委托都应该被取消。

实际上,我真的想不出任何原因,为什么会发生访问已释放对象的情况,无论是否有僵尸。如果引用是强引用,则不会释放对象。如果引用很弱,则在对象被释放时它会被取消。

然而,应用程序确实崩溃并出现错误:消息发送到已释放的实例 0x189f09c0

【问题讨论】:

    标签: ios objective-c


    【解决方案1】:

    您必须在 dealloc 方法中使用

    将委托设置为 nil
    scrollView.delegate = nil;
    

    释放的对象被释放(并从内存中删除)但未设置为 nil。您必须将其显式设置为 nil。

    【讨论】:

    • 我认为 scrollView.delegate 是一个弱引用。我认为当对象被释放时所有弱引用都会自动取消?
    • 对所有 scrollView 都这样做会很麻烦你不觉得吗?
    • 类中的weak属性可能为nil,但滚动视图的delegate属性仍然指向旧地址。即使听起来很麻烦,也别无选择
    • @JimThio:UIScrollViewdelegate 属性不弱!声明为@property(nonatomic, assign),“assign”与“unsafe_unretained”相同。所以它不会自动取消。
    • 什么?为什么 iPhone 决定使用分配?在什么天堂名称中会有人使用 assign 而不是 weak? Martin,您应该将其设置为 answre。
    【解决方案2】:

    您是否尝试过取消订阅 scrollView 的“通知”?

    - (void)dealloc
    {
        self.scrollView.delegate = nil; // or tableView, collectionView, etc.
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-11
      • 1970-01-01
      • 2017-04-10
      • 2023-01-08
      • 1970-01-01
      相关资源
      最近更新 更多