繁体   English   中英

将闭包作为参数传递给单例时的Swift内存管理

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM