gpt4 book ai didi

memory-management - 将引用转换回闭包内的强引用,内存管理,swift

转载 作者:行者123 更新时间:2023-12-01 13:42:32 24 4
gpt4 key购买 nike

我正在像下面这样在闭包中试验保留周期

 class Sample {
deinit {
print("Destroying Sample")
}

func additionOf(a: Int, b:Int) {
print("Addition is \(a + b)")
}

func closure() {
dispatch_async(dispatch_get_global_queue(0, 0)) { [weak self] in
self?.additionOf(3, b: 3)
usleep(500)
self?.additionOf(3, b: 5)
}
}
}

稍后在某个时候,我正在做

var sample : Sample? = Sample()
sample?.closure()

dispatch_async(dispatch_get_global_queue(0, 0)) {
usleep(100)
sample = nil
}

输出将是

Addition is 6
Destroying Sample

这是可以理解的,因为在执行 self?.additionOf(3, b:5) 之前 self 是 nil out

如果我通过创建另一个引用 [weak self] 的变量在闭包内部进行更改,如下所示

dispatch_async(dispatch_get_global_queue(0, 0)) { [weak self] in
guard let strongSelf = self else { return }
strongSelf.additionOf(3, b: 3)
usleep(500)
strongSelf.additionOf(3, b: 5)
}

这次的输出是

Addition is 6
Addition is 8
Destroying C

我的问题是为什么 strongSelfsample = nil 之后不为 nil。是不是因为在sample = nil

之前在闭包内部被捕获了

最佳答案

让我们考虑你的第二个例子:

dispatch_async(dispatch_get_global_queue(0, 0)) { [weak self] in
guard let strongSelf = self else { return }
strongSelf.additionOf(3, b: 3)
usleep(500)
strongSelf.additionOf(3, b: 5)
}

这是一个常见的模式,它有效地表示“如果 self 已被释放,立即返回,否则建立一个强引用,strongSelf ,并保持这个强引用,直到关闭完成。”

所以,在你的例子中,self 不是 nil 当这个分派(dispatch) block 开始时,所以一旦我们分配 strongSelf 来引用它,我们现在有两个对此 Sample 对象的强引用,原始的 sample 引用和这个闭包内的新的 strongSelf 引用。

因此,当您的其他线程删除了它自己对此 Sample 对象的强引用 sample 时(通过超出范围或通过显式设置 sample nil),这个 strongSelf 强引用仍然存在并且会阻止对象被释放(或者至少直到这个分派(dispatch) block 完成)。

在你上面的评论中,你问:

I still not understand why strongSelf does not get changed since self is nil out...

强引用永远不会设置为 nil 只是因为其他一些强引用(即使它是原始强引用)被设置为 nil。将引用设置为 nil 的行为仅适用于 weak 引用,不适用于强引用。

当您的代码在第一个线程上执行 sample = nil 时,所做的只是删除一个强引用。它不会删除对象或类似的东西。它只是删除了它的强引用。现在分派(dispatch)的 block 有自己的强引用,发生在 sample = nil 上的所有事情就是拥有两个强引用的对象现在只剩下一个强引用(strongSelf 分派(dispatch) block 中的引用)。只有当这个最终的强引用被移除时,对象才会被释放并调用 deinit

关于memory-management - 将引用转换回闭包内的强引用,内存管理,swift,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38779821/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com