我只是想知道我是否正确理解了这个问题。因此,根据苹果文档,当您将闭包创建为类实例的属性,并且该闭包引用self(创建闭包属性的类),这将导致强烈的保留循环,最终类和闭包都将永远不会被释放。因此,简单来说,如果我有一个具有属性的类,该属性是一个闭包,并且一旦我分配了声明闭包属性的类中的该闭包的功能,那么这将导致强大的保留循环。以下是我所指的快速示例
class SomeViewController{
let myClosure:()->Void
public func someFunction(){
....bunch of code
myClosure = {
self.dismiss(blahBlahBlah)
}
}
}
这最终会导致保留循环,因为闭包对创建闭包属性的类self保持强引用。现在根据苹果的建议,我将定义一个捕获列表,如下所示
class SomeViewController{
let myClosure:()->Void
public func someFunction(){
....bunch of code
myClosure = { [weak self] in
self?.dismiss(blahBlahBlah)
}
}
}
注意我在语句中把[weak self]放在in之前。这让闭包知道只保留对self的弱引用而不是强引用。当self可能比闭包存在时间更长或者self和闭包的生命周期相同时,应该使用weak或unowned。我从Automatic Reference Counting中获取了这些信息,在该链接的Strong Reference Cycles for Closures部分中有这样一句话:“如果将闭包分配给类实例的属性,并且该闭包的主体捕获了该实例,则也可能会发生强引用循环。”我大约90%确定我理解得正确,但还有10%的疑虑。所以我理解得对吗?
我之所以问这个问题,是因为我在我的视图中为一些按钮使用回调。那些回调会调用到self,但在这种情况下,self是响应回调的视图控制器,而不是实际的视图本身。这就是我怀疑自己的原因,因为从我突出显示的那句话来看,我不认为我需要在所有这些按钮回调上加上[weak self],但我只是想确认一下。以下是一个示例:
class SomeViewController {
let someSubview:UIView
override viewDidLoad() {
//Some Subview has a button and in that view I just have some action that gets fired off calling the callback here in the view controller I don't need to use the [weak self] in this scenario because closure property is not in this class correct?
someSubview.someButtonsCallback = {
....run code then
self?.dismiss(blahBlahBlah)
}
}
[weak self]
。然后,如果在闭包运行之前self可能被释放,我还需要设置一个强引用变量。我的另一个问题是,在从self运行函数时,什么情况下我们不需要设置捕获列表?例如,在HTTP调用中。由于闭包由调用HTTP方法的类拥有,并且该方法仅存在于调用它的函数的范围内。我不需要使用 weak self,对吗? - Esko918