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

bob*_*bob 2 singleton memory-management ios retain-cycle swift

我知道如果将它分配给类的属性并且在闭包内部使用类的实例属性,则closure可以创建retain cycles.但

1)闭包没有分配给类属性,而是作为参数传递给单例的类方法?

2)在这种情况下如何管理内存?

在我的控制器(UIViewController)的方法中,我有类似的东西:

MySingleton.classMethod(parameters ..., completion: { () -> Void in
   /**
   doing stuff here
   */
})
Run Code Online (Sandbox Code Playgroud)

Geo*_*iev 5

如果您没有将闭包赋值给属性,只是将它传递给函数您需要考虑闭包是否会转义或noescape.默认情况下,在Swift 3中,传递给函数的所有闭包都是非转义的.

以下是关于此事的更多信息:

"noescape" - 在函数返回之前调用传递的闭包

"转义" - 如果一个闭包作为一个参数传递给一个函数,并在函数返回后调用它,那么闭包就会转义.

简单的解释:我们需要在将函数传递给函数时将闭包标记为转义,并在此函数返回后调用闭包.

一般规则是关闭时逃逸您需要使用捕获列表来防止保留周期.

let closure = { [weak someVariable] (name: Type) -> Void in
....
// code
}
Run Code Online (Sandbox Code Playgroud)

附加信息:

一个奇怪的事情是可选的闭包被视为逃逸.当我们显式添加转义关键字时,有一个编译错误-escaping属性仅适用于函数类型.

有关详细信息,请参阅以下链接.

https://bugs.swift.org/browse/SR-2053

/sf/answers/2773350891/

/sf/answers/2789256361/

更新
在转义闭包的捕获列表中使用弱或无主的想法是,本质上我们不知道传递的转义闭包会发生什么,它可能稍后从另一个函数调用,或者它可能存储在某个对象中,这可能会导致强大的保留周期.

弱势与无主力与强势捕捉

有关更多详细信息,请查看Apple ARC文档.

来自Apple文档:

当您使用类类型的属性时,Swift提供了两种解决强引用循环的方法:弱引用和无引用引用.

弱引用和无引用引用使引用周期中的一个实例能够引用另一个实例而不保持强大的保持.然后,实例可以相互引用而不会创建强大的参考周期.

当另一个实例的生命周期更短时,即在可以首先释放另一个实例时,使用弱引用.当另一个实例具有相同的生命周期或更长的生命周期时,请使用无主引用.

请记住,弱方法会在代码中添加一个样板,并且会稍微慢一些,因为ARC会在释放时添加用于将弱变量设置为nil的代码.选择弱或无主时,遵循上述规则是一种好习惯.