【问题标题】:Storing weak reference sometimes causes leak存储弱引用有时会导致泄漏
【发布时间】:2018-12-22 17:56:21
【问题描述】:

我有一个class Aoptional weak variable 存储到其他对象,即subclassA。有时当我在这个变量中存储一些东西时,我会得到一个leak - 这种情况很少发生,但确实如此。我在forEach loop 中分配了这个变量,但是当我使用weak var 时,我在其他应用程序的地方也发现了类似的泄漏,所以我认为循环与此无关。负责库是libswiftCore.dylib,负责框架是swift::RefCounts<swift::RefCountBitsT<(swift::RefCountInlinedness)1> >::formWeakReference()。其他人有过类似的问题吗?有什么办法可以解决这个问题吗?

【问题讨论】:

  • 从未见过,但对于 Apple 框架中的泄漏,您应该提交错误报告。
  • 我有这个问题。我认为这是一个 Swift 问题,我不知道为什么它会在某些特定情况下发生。我能够通过使用Unmanaged<T> 来修复它,但我决定恢复修复以支持更具可读性的代码。仅供参考,就我而言,我存储在弱属性中的实际对象没有被保留,因此不解决问题对我来说是可以的。
  • 您能否提供一个最小可行的 sn-p 代码重现该问题,去掉与泄漏发生无关的任何内容?

标签: swift memory-leaks automatic-ref-counting


【解决方案1】:

尝试设置变量而不是weak,将其设置为unowned。 这是一种 Swift 错误,因为没有警告开发人员正在捕获嵌套闭包的强引用,但是,现在将其设置为 unowned 应该是一种解决方法。

编辑1:https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151207/001197.html

从这里提到的改进here

class ViewControllerBase: UIViewController {
let timer:DispatchSourceTimer = DispatchSource.makeTimerSource(flags: [], queue:  DispatchQueue(label: "q.q"))

deinit {
    NSLog("deinit of \(NSStringFromClass(type(of: self)))")
}

override func viewDidLoad() {
    super.viewDidLoad()

    timer.scheduleRepeating(deadline: .now(), interval: .seconds(1))

    timer.setEventHandler {
        UIView.animate(withDuration: 0.2) { [weak self] in
            self?.view.backgroundColor = UIColor.green
        }
    }
}

这会以一种微妙的方式泄漏内存......即使 self 仅以“弱”方式使用,也会有一个保留循环。这是因为嵌套闭包捕获了一个强引用,以便在后面的闭包中使用。

编辑 2: 我可能错了,但 OP 使用 changes.forEach 闭包,然后使用 changes.added.forEach 进行另一个闭包我可能是错的,但这可能是整个问题的原因,也许在 [weak self] (cluster, change) in ... 中声明它可能会删除问题。它是 swifts 内置闭包,但仍然是闭包,从技术上讲,这可能会导致它们嵌套。

尝试将您的代码更改为:

changes.forEach{[weak self] (cluster, change) in

看看有没有帮助

changes.forEach{[unowned self] (cluster, change) in

您还可以粘贴代码而不是截屏,因为重新创建代码而不是重新输入代码更容易。

【讨论】:

  • unownedweak 有不同的含义 - weak 根据定义是可选的,必须在使用前解包(安全或不),我们可以安全地检查它是否为 nil(因为它是可选的)。 unowned 不能是可选的,因此它不适用于我需要使用 weak(并检查 nil)的情况。至于“这是错误” - 你能引用任何权威来源吗?
  • 尽管您提供的信息非常有用 (imo) 并且给了我很多思考它是关于一个涉及两个嵌套闭包的特殊情况。我没有这样的代码,我只有weak var(就像问题作者一样),它仍然会产生泄漏。
  • 你能把你的代码分享到某个地方让我看看吗??
  • 从我现有的代码中制作最小的可重现示例需要一些时间,并且可能是关于 SO 的另一个问题。我希望看到这个问题的快速解决方案。如果我们在几天内没有看到其他答案,我会这样做。
  • 我可能错了,但 OP 使用 changes.forEach 闭包,然后使用 changes.add.forEach 闭包我可能是错的,但这可能是整个问题的原因,也许在那里声明[ weak self] (cluster, change) in ... 可能会解决这个问题。它是 swifts 内置闭包,但仍然是闭包,从技术上讲,这可能会导致它们嵌套。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-09
  • 2012-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多