[英]Swift Memory management when pass a closure as parameter to singleton
我知道以下事实:如果将closure
分配给一个类的属性,并且该类的实例属性在闭包内部使用,则它可以创建retain cycles
。 但
1) 关闭没有分配给class属性,而是作为参数传递给单例的class方法呢?
2) 在这种情况下如何管理内存?
在我的控制器(UIViewController)的方法中,我有类似以下内容:
MySingleton.classMethod(parameters ..., completion: { () -> Void in
/**
doing stuff here
*/
})
如果您不是将闭包分配给属性,而只是将其传递给函数,则需要考虑闭包是转义还是转义。 在Swift 3中,默认情况下,传递给函数的所有闭包都是非转义的。
以下是有关此问题的更多信息:
“ noescape”-在函数返回之前调用传递的闭包
“转义”-如果将闭包作为参数传递给函数,并且在函数返回后调用该闭包,则闭包正在转义。
简单说明:当我们将闭包传递给函数时,需要将闭包标记为转义,并且在此函数返回后将调用闭包。
一般规则是闭包转义时,您需要使用捕获列表来防止保留周期。
例
let closure = { [weak someVariable] (name: Type) -> Void in
....
// code
}
附加信息:
一件奇怪的事情是,可选的闭包被视为转义。 当我们显式添加转义关键字时,会出现编译错误-转义属性仅适用于函数类型。
有关更多信息,请参见以下链接。
https://bugs.swift.org/browse/SR-2053
https://stackoverflow.com/a/39619298/5388473
https://stackoverflow.com/a/39846519/5388473
更新
在转义闭包的捕获列表中使用弱或未拥有的想法是,基本上我们不知道所传递的转义闭包会发生什么,它可能稍后会从另一个函数中调用,或者可能存储在某个对象中,可能会导致强大的保留周期。
弱者vs无人者vs强势捕获
有关更多详细信息,请查看Apple ARC文档 。
从苹果文档:
使用类类型的属性时,Swift提供了两种解决强引用周期的方法:弱引用和无主引用。
弱引用和无主引用使引用周期中的一个实例可以引用另一个实例,而无需对其进行严格控制。 然后,这些实例可以相互引用,而无需创建强大的引用周期。
当另一个实例的生存期较短时(即,另一个实例可以首先被释放时),请使用弱引用。 当另一个实例具有相同的生存期或更长的生存期时,请使用无主引用。
请记住,弱方法将在代码中添加样板,并且速度会稍慢一些,因为ARC将添加用于将弱变量设置为零的代码。 当选择弱者或无人者时,遵循上述规则是一个好习惯。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.