这不是关于[weak self]
的另一个问题。这是关于使用self
未包含的变量,而是使用包装函数。
func someFunction(){
someOtherFunction(completionBlock:{ [weak self] in
self?.doStuff()
})
}
据我了解,我需要[weak self]
才能阻止保留周期。
但是,如果我需要使用包装函数中的变量,如下所示:
func someFunction(){
let someVariable = MyObject()
someOtherFunction(completionBlock:{ [weak self] in
self?.doStuff(with: someVariable)
})
}
这有效,这让我很奇怪.. someVariable
在记忆中的持续时间和持续时间有多长?它可以创建自己的小保留周期,我的完成块强烈引用本地someVariable
吗?它们将如何发布? 应该我在块中添加[weak self, weak someVariable]
吗?但是,在我致电someVariable
后立即释放someOtherFunction
,因为它是此功能的结束 - 以及someVariable
'一生......?
我无法完全理解参考文献,也无法看到我的completionBlock
和someVariable
将如何发布..块是否已被释放?
答案 0 :(得分:4)
闭包内引用的任何变量都将被该闭包强烈保留。您可以通过包含闭包捕获列表(例如[weak self]
)来调整它,这允许您指定闭包中捕获的引用的特定内存管理模式。
func someFunction(){
let someVariable = MyObject()
someOtherFunction(completionBlock:{ [weak self] in
self?.doStuff(with: someVariable)
})
}
正如您所说,此处,闭包保留someVariable
。在这种情况下,它有,因为没有其他人关心它。正如您在评论中提到的那样,如果您使用了[weak someVariable]
的捕获列表,那么在执行完成块时它总是为零,因为它已经超出了它的原始功能范围。
A"微小的保留周期"没有被创造。保留周期必须是周期 - 也就是说,A保存对B的强引用,B具有对A的强引用。someVariable
没有引用任何内容。
一旦someOtherFunction
完成对完成闭包的引用,一切都会消失。就someOtherFunction
而言,闭包只是另一个变量,只要它在范围内,它就会存活下来。
我应该弱化块中使用的“局部”变量吗? - 不,因为它们在块使用它们时将为零。
答案 1 :(得分:0)
我想提一下不那么明确的选项,创建保留周期的常用位置是什么,以及应该注意弱化变量的地方。
让我们考虑一下这种情况:
func someFunction() {
let object = Something()
object.handler = { [weak self] in
self?.doStuff(with: object)
}
}
现在有保留周期,并且在有人手动取消设置object
之前,handler
无法取消分配。因为现在对象在捕获的块中强化自身。
更好的解决方案是:
func someFunction() {
let object = Something()
object.handler = { [weak self, unowned object] in
self?.doStuff(with: object)
}
}
好的做法是在object
handler
作为参数
func someFunction() {
let object = Something()
object.handler = { [weak self] (object) in
self?.doStuff(with: object)
}
}
所以签名应该是这样的:
class Something {
var handler:((Something) -> Void)?
deinit {
print("retain cycle is not here")
}
}