在Swift中阻止保留周期?

时间:2014-06-04 16:38:42

标签: swift

传统上在Objc中,我们使用weakSelf来防止块的额外保留计数。

swift如何在内部管理Objc的块中发生的保留周期?

3 个答案:

答案 0 :(得分:94)

要防止块保持对对象的强引用,必须为块定义捕获列表。

闭包表达式语法定义如下:

{ ( /*parameters*/ ) -> /*return type*/ in

    // statements
}

但是稍后会在文档中扩展以包含捕获列表。这有效地等同于表达式语法定义如下:

{ [ /*reference type*/ /*object*/, ... ] ( /*parameters*/ ) -> /*return type*/ in

    // statements
}

...其中/*reference type*/可以是weakunowned

捕获列表是第一个出现在闭包中的东西,它是可选的。如上所示,语法被定义为一对或多对引用类型,后跟object;每对用逗号分隔。例如:

[unowned self, weak otherObject]

完整示例:

var myClosure = {
    [unowned self] in
    print(self.description)
}

请注意,unowned引用是非可选的,因此您无需打开它。

希望能回答你的问题。您可以在documentation的相关部分中阅读有关Swift中ARC的更多信息。

您应该特别注意weakunowned之间的区别。在您的实现中使用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()
    }             
}