ios - 为什么在属性中包装 ReactiveSwift MutableProperty 会导致泄漏?

标签 ios swift memory-leaks reactive-cocoa reactive-swift

这是一个使用 ReactiveSwift 的 Swift 类,将 MutableProperty 包装在 Property 中,并在 中添加对该 Property 的订阅>ScopedDisposable:

class Leaker {
    let mutableProperty = MutableProperty<Int>(0)

    var wrapperProperty: Property<Int> {
        return Property(self.mutableProperty)
    }

    private var disposable: ScopedDisposable<AnyDisposable>?

    init() {
        let disposable = CompositeDisposable()

        disposable += self.wrapperProperty.producer
            .startWithValues { value in
                print("\(value)")
            }

        self.disposable = ScopedDisposable(disposable)
    }
}

如果我给另一个类一个 Leaker? 类型的属性,然后使用 self.leaker = Leaker() 设置它,这会造成泄漏。我所说的“造成泄漏”是指它触发了 Leaks 工具,显示了一个标记为 Malloc 32 Bytes 的泄漏对象,以及包含 Leaker.init() 的堆栈跟踪调用 Leaker.wrapperProperty.getter

为什么会泄漏?我发现很难准确理解是什么导致此处分配的内存永远不会被释放。

其他一些可能有用的事实:

  • 如果我直接订阅 mutableProperty,这不会泄漏
  • 如果我将 mutableProperty 包装在惰性属性而不是计算属性中,这不会泄漏
  • 如果我创建一个临时的 Leaker,这不会泄漏,例如让 _ = Leaker()

最佳答案

我试过了,但无法重现内存泄漏。我在这段代码中使用了你的 Leaker 类:

final class OtherClass {
  let leaker: Leaker?

  init() {
    self.leaker = Leaker()
  }
}

var otherClass: OtherClass? = OtherClass()

var mutablePropertyCompleted = false
otherClass!.leaker!.mutableProperty.producer.startWithCompleted {
  mutablePropertyCompleted = true
}

var wrappedPropertyCompleted = false
otherClass!.leaker!.wrapperProperty.producer.startWithCompleted {
  wrappedPropertyCompleted = true
}

otherClass = nil

if(!mutablePropertyCompleted) {
  print("LEAK")
}

if(!wrappedPropertyCompleted) {
  print("LEAK")
}

需要注意的一件事是 MutableProperty 在它的 deinit 方法中发送了 completed ,所以应该可以像我这样检测泄漏在这里做了。

但为了确定,我还使用未检测到任何内容的内存泄漏工具对此进行了概要分析。

既然你提到了一些特定的情况,在这些情况下这不会对你造成泄漏,这可能只是我尝试重现问题的方式是错误的,也许你可以发布一个完整的例子?

无论如何,我在您发布的示例中没有看到错误,所以这要么是 ReactiveSwift 中的错误,要么是探查器的误报(正如 jjoelson 在他的评论中指出的那样,ReactiveSwift 之前已经发生过这种情况)

关于ios - 为什么在属性中包装 ReactiveSwift MutableProperty 会导致泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47680349/

相关文章:

ios - 在 Xcode 中使用 iPad 和 iPhone Storyboard

ios - Skobbler map 聚类

ios - 空 tableView 上没有结果标签

ios - 看起来 Apple 在 UIActivityViewController 中错误地转换了字符串

c++ - QTcpSocket "leaks"内存

ios - 如何在 firebase firestore 数据库中标记和报告用户?

ios - 从 HealthKit 获取一系列血糖记录

ios - 如何修复 mapKit Ios 中使用的过多内存?

ios - 如何在 Swift 中更改 UILabel 的字体大小?

ios - 如何调查 ios 中的内存泄漏?