【发布时间】:2023-04-08 09:19:01
【问题描述】:
我试图解释对象的所有权以及 GCD 是如何工作的。 这些是我学到的东西:
- 函数将增加其调用对象的保留计数
- 一个调度块,除非它弱捕获
self会增加计数。 - 在调度块执行后,它释放捕获的对象,因此
self的保留计数应该减少。但这不是我在这里看到的。这是为什么?
class C {
var name = "Adam"
func foo () {
print("inside func before sync", CFGetRetainCount(self)) // 3
DispatchQueue.global().sync {
print("inside func inside sync", CFGetRetainCount(self)) // 4
}
sleep(2)
print("inside func after sync", CFGetRetainCount(self)) // 4 ?????? I thought this would go back to 3
}
}
用法:
var c: C? = C()
print("before func call", CFGetRetainCount(c)) // 2
c?.foo()
print("after func call", CFGetRetainCount(c)) // 2
【问题讨论】:
-
保留计数与您的预期不同的原因有很多。比较 stackoverflow.com/questions/4636146/when-to-use-retaincount、friday.com/bbum/2011/12/18/retaincount-is-useless 或 sdarlington.github.io。 – 在您的情况下,Debug 和 Release 模式的行为是不同的。
-
@MartinR FWIW 我也使用异步块测试了这个,它以非
weak的方式捕获了self,使用了捕获自我weakly 的异步块,或者调用了多个异步块。保留计数的增加/减少,我能够为所有这些合理化,除了这个。但我明白你在说什么,这是未知的。我在这里问我的问题是因为我认为有人可能知道答案。或者我对同步块如何工作的理解不正确 -
@MartinR 我的期望正确吗?执行后应该减少吗?
-
从那个链接,bbum 还提到:“一般来说,您应该将保留计数视为增量。您的代码导致保留计数增加和减少。您不't +alloc 保留计数为 1 的对象。相反,您 +alloc 保留计数为 +1 的对象。如果您希望该对象消失,您需要做一些事情——释放,总是和最终——导致保留计数减 1。”这正是我正在做的。所以这是一个有效的用例。
-
请注意,如果代码在发布模式下编译,即进行优化,则保留计数的行为与您预期的一样。
标签: swift multithreading memory-management grand-central-dispatch retaincount