Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift GCD中的弱Self,访问Self的TableView属性_Swift_Closures_Grand Central Dispatch - Fatal编程技术网

Swift GCD中的弱Self,访问Self的TableView属性

Swift GCD中的弱Self,访问Self的TableView属性,swift,closures,grand-central-dispatch,Swift,Closures,Grand Central Dispatch,我看到很多这样的代码: DispatchQueue.main.async { self.tableView.reloadData() } DispatchQueue.main.async { [weak self] in self?.tableView.reloadData() } DispatchQueue.main.async { [weak self] in self?.tableView.reloadData() } 在这种情况下,如果tableView是s

我看到很多这样的代码:

DispatchQueue.main.async {
    self.tableView.reloadData()
}
DispatchQueue.main.async { [weak self] in
    self?.tableView.reloadData()
}
DispatchQueue.main.async { [weak self] in
    self?.tableView.reloadData()
}
在这种情况下,如果tableView是self的一个属性,那么是否应该改为确保捕获弱self,如下所示:

DispatchQueue.main.async {
    self.tableView.reloadData()
}
DispatchQueue.main.async { [weak self] in
    self?.tableView.reloadData()
}
DispatchQueue.main.async { [weak self] in
    self?.tableView.reloadData()
}
我想是的,但是这种类型的不安全代码在代码库中无处不在,我想知道我是否遗漏了什么

在这种情况下,如果tableView是self的一个属性,那么是否应该改为确保捕获弱self,如下所示:

DispatchQueue.main.async {
    self.tableView.reloadData()
}
DispatchQueue.main.async { [weak self] in
    self?.tableView.reloadData()
}
DispatchQueue.main.async { [weak self] in
    self?.tableView.reloadData()
}
不,在这种情况下,实际上不需要对self使用弱引用。这里没有持久的强引用循环。在没有弱引用的情况下,最糟糕的情况是,它将保持对self的强引用,直到调度的块完成运行。但这种关闭通常会立即进行,短暂的强引用将很快被消除

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

顺便说一句,“不安全”一词的选择让这个话题有点混乱。在谈到内存引用时,“不安全”有一个非常具体的含义:它通常指在不使用运行时安全检查时挂起对已解除分配对象的引用。正如原文强调的那样:

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

通过写入unownedunsafe来指示不安全的unowned引用。如果在取消分配引用的实例后尝试访问不安全的无主引用,则程序将尝试访问该实例以前所在的内存位置,这是一个不安全的操作

显然,强引用和弱引用都是安全的——前者防止对象被释放,后者在对象被释放时将其引用设置为nil。即使无主引用也经常使用运行时安全检查,尽管如果在对象解除分配后使用无主引用,仍然会导致运行时错误。在高性能场景中使用“不安全”引用,在这种场景中,您完全有信心您的无主引用被正确处理,并且您愿意在不进行运行时安全检查的情况下运行代码

我怀疑你在这里不是指“不安全”,但我提到它是为了让你知道这个词在ARC和内存管理中的具体含义。

你说:

在这种情况下,如果tableView是self的一个属性,那么是否应该改为确保捕获弱self,如下所示:

DispatchQueue.main.async {
    self.tableView.reloadData()
}
DispatchQueue.main.async { [weak self] in
    self?.tableView.reloadData()
}
DispatchQueue.main.async { [weak self] in
    self?.tableView.reloadData()
}
不,在这种情况下,实际上不需要对self使用弱引用。这里没有持久的强引用循环。在没有弱引用的情况下,最糟糕的情况是,它将保持对self的强引用,直到调度的块完成运行。但这种关闭通常会立即进行,短暂的强引用将很快被消除

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

顺便说一句,“不安全”一词的选择让这个话题有点混乱。在谈到内存引用时,“不安全”有一个非常具体的含义:它通常指在不使用运行时安全检查时挂起对已解除分配对象的引用。正如原文强调的那样:

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

通过写入unownedunsafe来指示不安全的unowned引用。如果在取消分配引用的实例后尝试访问不安全的无主引用,则程序将尝试访问该实例以前所在的内存位置,这是一个不安全的操作

显然,强引用和弱引用都是安全的——前者防止对象被释放,后者在对象被释放时将其引用设置为nil。即使无主引用也经常使用运行时安全检查,尽管如果在对象解除分配后使用无主引用,仍然会导致运行时错误。在高性能场景中使用“不安全”引用,在这种场景中,您完全有信心您的无主引用被正确处理,并且您愿意运行 您的代码没有运行时安全检查


我怀疑你在这里不是指“不安全”,但我提到它是为了让你知道这个词在ARC和内存管理中的具体含义。

为什么你认为第二个不安全?@zeytin-我猜伍德斯托克并不担心第二个,而是担心第一个。他可能担心它引入了一个强大的参考循环,但它没有。不过这没关系,因为这两种都不安全。事实上,他使用了“不安全”一词,这在内存管理中有着非常不同和非常具体的含义,这也可能是一个意外。你为什么认为第二个是不安全的?@zeytin-我猜伍德斯托克并不担心第二个,而是担心第一个。他可能担心它引入了一个强大的参考循环,但它没有。不过这没关系,因为这两种都不安全。事实上,他使用了“不安全”一词,这在内存管理中有着非常不同和非常具体的含义,这可能也是一个意外。谢谢@Rob-一如既往。我知道如果一个闭包捕获了self,self捕获了闭包,就会创建一个强ref循环。我猜self对GCD区块没有一个长寿命的属性样式引用,是吗?问题是闭包的所有者在调用闭包后对闭包做了什么。在GCD的例子中,他们非常擅长在完成闭包后释放闭包,从而打破了强引用“循环”。但对于重复计时器或通知观察者之类的东西,显然无法释放闭包,因此我们必须使用弱自模式。情况各不相同。谢谢@Rob-一如既往。我知道如果一个闭包捕获了self,self捕获了闭包,就会创建一个强ref循环。我猜self对GCD区块没有一个长寿命的属性样式引用,是吗?问题是闭包的所有者在调用闭包后对闭包做了什么。在GCD的例子中,他们非常擅长在完成闭包后释放闭包,从而打破了强引用“循环”。但对于重复计时器或通知观察者之类的东西,显然无法释放闭包,因此我们必须使用弱自模式。情况各不相同。