我正在尝试在Swift中解决基于闭包的强引用循环
在下面的代码中,对象由拥有的视图控制器保留。 ProgressHUD
是UIView
,也由拥有的视图控制器保留。每次调用完成处理程序时都会泄漏ProgressHUD
。使用新的闭包捕获功能时,将self声明为weak或unowned并不能解决内存泄漏问题。
object.setCompletionHandler { [weak self] (error) -> Void in
if(!error){
self?.tableView.reloadData()
}
self?.progressHUD?.hide(false)
}
但是,如果我在闭包之外为self声明一个弱变量,它会修复内存泄漏,如下所示:
weak var weakSelf = self
object.setCompletionHandler { (error) -> Void in
if(!error){
weakSelf?.tableView.reloadData()
}
weakSelf?.progressHUD?.hide(false)
}
关于为什么这不适用于Swift捕获的任何想法?
答案 0 :(得分:13)
如果为类实例的属性分配闭包,并且闭包通过引用实例或其成员来捕获该实例,则将在闭包和实例之间创建一个强引用循环。 Swift使用捕获列表来打破这些强大的参考周期。 source Apple
source sketchyTech首先,重要的是要明确整个问题只涉及我们将“闭包分配给类实例的属性”的闭包。每条规则都要牢记这一点。 规则:
对于你的问题,应该没有保留周期。
答案 1 :(得分:5)
你声明progressHUD由拥有的视图控制器(self)保留,你在闭包中引用它...所以将它添加到捕获列表中,然后在闭包中使用捕获的变量,如下所示:
object.setCompletionHandler { [weak self] (error) -> Void in
if(!error){
self?.tableView.reloadData()
}
self?.progressHUD.hide(false)
}
答案 2 :(得分:-2)
这就是我一直在做的事情:
object.setCompletionHandler { [weak self] (error) -> Void in
if let weakSelf = self {
if (!error) {
weakSelf.tableView.reloadData()
}
weakSelf.progressHUD?.hide(false)
}
}
答案 3 :(得分:-4)
尝试以下方法:
object.setCompletionHandler { [unowned self] (error) -> () in
if(!error){
weakSelf?.tableView.reloadData()
}
weakSelf?.progressHUD?.hide(false)
}