- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在像下面这样在闭包中试验保留周期
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
我的问题是为什么 strongSelf
在 sample = 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 isnil
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/
我在一个 twig 模板中使用 Assetic 来指定要从我的包中使用的 2 个 JS 文件 { % javascripts '@JiraExtendedReportsBund
我正在做一个 VS 包,它在菜单中有一个 DynamicItemStart 按钮。我在 VS 启动时加载动态按钮的内容没有任何问题,但我试图在某些事件(例如打开项目)之后向其内容添加更多命令。我将新命
需求是从plsql调用java方法,我可以通过loadjava命令来实现它。我遵循的步骤是: 第 1 步:创建 Java Class/jar 文件并将其放置在 Unix 机器上 第2步:将Java C
我是一名优秀的程序员,十分优秀!