GCD中的弱Self,正在访问Self的TableView属性



我看到很多这样的代码:

DispatchQueue.main.async {
self.tableView.reloadData()
}

在这种情况下,如果tableViewself的属性,是否应该确保weak self被捕获为如下:

DispatchQueue.main.async { [weak self] in
self?.tableView.reloadData()
}

我想是的,但这种类型的";"不安全";代码在代码库中无处不在,我想知道我是否遗漏了什么?

你说:

在这种情况下,如果tableViewself的属性,是否应该确保weak self被捕获如下:

DispatchQueue.main.async { [weak self] in
self?.tableView.reloadData()
}

不,在这种情况下,实际上不需要使用weak引用self。这里没有持久的强参考循环。最糟糕的情况是(在没有weak引用的情况下(,它将保持对self的强引用,直到调度的块完成运行。但这种关闭通常会立即进行,短暂的强烈参考会很快被消除。

因此,不,您不必在此处使用weak引用。这样做在技术上并没有错,但增加了语法噪音,实际上没有任何好处。是的,我们应该努力打破weak引用的潜在强引用循环,但这不是其中之一。


顺便说一句,"不安全"一词的选择有点混淆了话题。当谈到内存引用时,"不安全"有一个非常具体的含义:它通常指在不使用运行时安全检查时对已释放对象的悬挂引用。正如Swift编程语言:自动参考计数所说(强调原文(:

Swift还为需要禁用运行时安全检查的情况提供不安全无主引用,例如出于性能原因。与所有不安全的操作一样,您有责任检查该代码的安全性。

您可以通过编写unowned(unsafe)来指示不安全的无主引用。如果在释放引用所引用的实例后尝试访问不安全的无主引用,则程序将尝试访问该实例曾经所在的内存位置,这是不安全的操作。

显然,强引用和弱引用都是安全的(前者阻止对象被释放,后者在对象被释放时将其引用设置为nil(。即使是unowned引用也经常使用运行时安全检查(尽管如果在对象被释放后使用unowned引用,仍然会导致运行时错误(。"不安全"引用用于高性能场景,在这些场景中,您绝对相信您的无主引用得到了正确处理,并且您愿意在没有运行时安全检查的情况下运行代码。

我怀疑你在这个上下文中的意思不是"不安全",但我提到它是为了让你意识到这个词在ARC和记忆管理上下文中的特殊含义。

最新更新