【问题标题】:Strange behaviour of Swift ClosureSwift 闭包的奇怪行为
【发布时间】:2019-11-30 16:52:18
【问题描述】:

正如苹果在 swift 文档中描述的那样,闭包是引用类型。所以每次当我将闭包分配给另一个引用变量时,只会复制引用。我尝试了下面的代码,在这里我发现了一个奇怪的快速关闭行为。在这里,我创建了一个 MyClass 对象并将其分配给 obj。这个对象被 cls1、cls2cls3 引用的闭包捕获。当我调用此方法时,我得到 MyClass 对象的保留计数为 5。但是如果闭包是引用类型,则闭包对象的保留计数应该不会增加 MyClass 对象,但这里 MyClass 对象的保留计数会增加。

class ABC{

        class MyClass{}

        static func get(){
            let obj: MyClass = .init()

                let cls1: (()->Void) = {
                    print(obj)
                }
                let cls2 = cls1
                let cls3 = cls1
                let count = CFGetRetainCount(obj)
                print(count)
        }
}

【问题讨论】:

  • 我没有发现任何奇怪的地方,你在你的闭包中“捕获”obj 并将引用传递给cls2cls3
  • CFGetRetainCount 没有任何意义。比什么都少。 stackoverflow.com/questions/4636146/when-to-use-retaincount 你忘记了自动释放的存在,它增加了保留计数,这些计数将在不久的将来被删除。如果你用优化重新编译这段代码,你可能会得到一个完全不同的结果,但它仍然没有意义。
  • 我不认为这是对这个问题的公平批评。虽然我们不应将程序的正确行为基于实现细节,但我们仍然可以从了解这些细节中受益。

标签: swift


【解决方案1】:

首先,您不能可靠地使用保留计数来跟踪对象所有权。有太多复杂的因素超出了您的意识或控制范围。

其次,您忘记了闭包从其封闭范围捕获对象。

【讨论】:

  • “太多复杂的因素超出了你的意识或控制范围”——但这个问题的重点是了解这些因素是什么!至于“闭包捕获对象”——好吧,但是为什么复制对闭包的引用会增加闭包捕获的对象的引用计数?毕竟,复制对视图的引用不会增加视图子视图的引用计数。
  • @robmayoff 你是对的。我只想知道为什么闭包在我的代码中表现得像值类型而不是引用类型。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 2016-01-28
  • 2019-01-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多