传统上在Objc中,我们使用weakSelf来防止块的额外保留计数。
swift如何在内部管理Objc的块中发生的保留周期?
答案 0 :(得分:94)
要防止块保持对对象的强引用,必须为块定义捕获列表。
闭包表达式语法定义如下:
{ ( /*parameters*/ ) -> /*return type*/ in
// statements
}
但是稍后会在文档中扩展以包含捕获列表。这有效地等同于表达式语法定义如下:
{ [ /*reference type*/ /*object*/, ... ] ( /*parameters*/ ) -> /*return type*/ in
// statements
}
...其中/*reference type*/
可以是weak
或unowned
。
捕获列表是第一个出现在闭包中的东西,它是可选的。如上所示,语法被定义为一对或多对引用类型,后跟object;每对用逗号分隔。例如:
[unowned self, weak otherObject]
完整示例:
var myClosure = {
[unowned self] in
print(self.description)
}
请注意,unowned
引用是非可选的,因此您无需打开它。
希望能回答你的问题。您可以在documentation的相关部分中阅读有关Swift中ARC的更多信息。
您应该特别注意weak
和unowned
之间的区别。在您的实现中使用weak
可能更安全,因为使用unowned
假设对象永远不会为零。如果在关闭中使用对象之前实际已经解除分配,这可能会导致应用程序崩溃。
使用weak
作为参考类型,您应该使用?
解包,如下所示:
var myClosure = {
[weak self] in
print(self?.description)
}
答案 1 :(得分:13)
唯一能让我离开捕获列表的是什么时候使用弱vs无主。
这本书将其简化为以下规则:
如果封闭使用自我可能是零[弱自我]。
如果封闭使用自己将永远不会是[无主自我]。
有关更深入的解释,请参阅The Swift Programming Language book中的弱无引用部分。
答案 2 :(得分:6)
如上所述,有两种方法可以避免在Swift中保留周期,这些是initComponent: function(){
var me = this,
myId = 20;
me.callParent(arguments);
var store = me.getStore();
store.getProxy().extraParams = {
ID:myId
}
}
和weak
,如下所述:
unowned
var sampleClosure = { [unowned self] in
self.doSomething()
}
永远不会是self
。
nil
其中var sampleClosure = { [weak self] in
self?.doSomething()
}
需要使用self
解包。
这里有一个重要的观察要做,如果有更多使用自我的指令并且可以分享结果等,可能的正确方法可能是:
?
或
var sampleClosure = { [weak self] in
if let this = self{
this.doSomething()
this.doOtherThings()
}
}