当不在闭包内时,传递属于self的函数是否会导致保留循环?

6

如果您需要在闭包内引用self,最好将其作为weakunowned传递以防止循环引用。

如果我直接传递属于self的函数,会导致循环引用吗?还是需要将其嵌套在闭包内以使self弱化?

直接传递

UIView.animateWithDuration(0.3,
        delay: 0.0,
        usingSpringWithDamping: 0.7,
        initialSpringVelocity: 0.1,
        options: .CurveEaseOut,
        animations: self.view.layoutIfNeeded, // does this cause retain cycle? 
        completion: nil)

使用闭包进行封装

UIView.animateWithDuration(0.3,
        delay: 0.0,
        usingSpringWithDamping: 0.7,
        initialSpringVelocity: 0.1,
        options: .CurveEaseOut,
        animations: { [unowned self] in
            self.view.layoutIfNeeded()
        },
        completion: nil)
2个回答

3

这不应该创建一个引用循环,但即使它这样做了,也没关系。引用循环只会存在到动画完成的时候才会被打破。创建短暂的引用循环实际上是有益的,因为它确保目标在调用的生命周期内继续存在。循环本身并不是问题,不能被打破的循环才是问题。

这里有两个原因为什么这不会创建循环。首先,没有“循环”。系统肯定会引用某些东西(稍后会详细介绍),但是“引用那个东西的东西”的引用在哪里呢?更清楚地说,即使动画系统引用了selfself又如何引用动画系统呢?没有循环。

另一个原因是你根本没有将self传递给动画系统。你传递的是self.view.layoutIfNeeded。在Swift中,这相当于:

UIView.layoutIfNeeded(self.view)

在这里你没有传递 self。而是传递了一个视图。现在动画系统几乎肯定会保留对该视图的引用,直到动画完成,但是这没关系。这仍然不算是一个循环。


1
由于self没有捕获闭包,所以没有引用循环,但如果您不想让self有另一个强引用,可以使用包装闭包。
如果您确定self在接下来的0.3秒内不会被释放,您可以使用unowned,否则使用weak。(我建议使用weak以确保它不会崩溃)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接