有这样的事吗?下面两个有什么区别吗?比另一个更“正确”吗?
所有对象都是self
的属性(比如一个视图控制器),其生命周期与self
相同。我们可以引入一个寿命比self
更短的对象,weak
,但同样的问题适用。
objectOne.doSomething { [unowned self] in
self.objectTwo.finish()
self.tableView.reloadData()
// self.someDelegate?.didFinishSomething()
}
VS
objectOne.doSomething {
[unowned objectTwo = self.objectTwo,
unowned tableView = self.tableView
// weak someDelegate = self.delegate
] in
objectTwo.finish()
tableView.reloadData()
// someDelegate?.didFinishSomething()
}
Apple在their docs中有这个例子:
lazy var someClosure: () -> String = {
[unowned self, weak delegate = self.delegate!] in
// closure body goes here
delegate?.doSomething()
}
在这种情况下,delegate
的生命周期可能比self
短,但为什么不这样使用呢?
lazy var someClosure: () -> String = {
[unowned self] in
// closure body goes here
self.delegate?.doSomething()
}
答案 0 :(得分:1)
是的,有一个重要的区别。对于Apple文档,您提供了代码替代方案:
lazy var someClosure: () -> String = {
[unowned self] in
// closure body goes here
self.delegate?.doSomething()
}
当闭包运行时,将在delegate
上查找当前 self
。
在Apple示例版本中:
lazy var someClosure: () -> String = {
[unowned self, weak delegate = self.delegate!] in
// closure body goes here
delegate?.doSomething()
}
捕获列表中的弱delegate
var是复制关闭声明时存在的delegate
上的self
指针,而不是执行。因此,如果self.delegate
的值在声明闭包后发生变化,并且在闭包运行时不同,那么闭包的Apple版本将具有一个nil委托(假设因为对旧委托的引用很弱)并且什么都不做。
因此,作为一般规则,在捕获列表([someIdentifier = someProperty]
)中复制值或引用是如何使用在定义闭包时存在的值或引用。虽然在捕获列表([weak self]
)中声明弱或无主,然后访问该弱引用({ self?.someProperty }
)上的属性,但在闭包执行时将获得属性的值
答案 1 :(得分:0)
[unowned objectOne = self.objectOne]
可能导致的一个问题是lazy var UIViews
和竞争条件:如果你不小心,lazy
init从不同的线程调用,两个实例可能最终被创造出来。此外,如果您的superview.addSubview(objectOne)
调用位于lazy
初始化版中,则两个实例都将添加到superview
,objectOne
将指向这两个实例中的一个。