有没有办法向"客户"一个特定的方法,将保留一个闭包参数?
例如,拥有以下代码:
import Foundation
typealias MyClosureType = () -> Void
final class MyClass {
private var myClosure: MyClosureType?
func whatever(closure: MyClosureType?) {
myClosure = closure
}
}
任何人都可以开始使用此类并将闭包传递给方法whatever
,而不知道它是否实际被保留。哪个容易出错,可能导致内存泄漏。
例如,"客户"做这样的事情,永远不会被解除分配
final class MyDummyClient {
let myInstance = MyClass()
func setUp() {
myInstance.whatever {
self.whateverHandler()
}
}
func whateverHandler() {
print("Hey Jude, don't make it bad")
}
}
这就是为什么我想知道是否有任何方法可以防止此类错误。某些类型的参数我可以添加到我的方法whatever
的定义中,它向客户提供了关于弱化以避免泄漏的需要
答案 0 :(得分:2)
闭包参数是否转义或非转义是调用者是否可以保留的一些指示。特别是,函数调用不能 -escaping闭包参数 。
按SE-0103,非转义闭包(当前标记为@noescape
)将成为Swift 3中的默认值,如果要保存闭包,则必须编写@escaping
,所以这样的情况会变得更加明显。
否则,没有语言功能可以帮助您。您必须使用API设计和文档解决此问题。如果它类似于处理程序,我会推荐一个属性obj.handler = { ... }
或类似obj.setHandler({ ... })
或obj.addHandler({ ... })
的方法。这样,在阅读代码时,您可以轻松地告知由于=
或set
或add
而正在保存闭包。
(实际上,在确定是否警告用户关于保留周期时编译Obj-C,Clang explicitly looks for methods named set...:
or add...:
时。将来可能会向Swift编译器添加类似的诊断。)
答案 1 :(得分:0)
对于特定情况,你提出的闭包本身是唯一可以保留的东西,所以如果你在调用时正确地将[弱自我]添加到你的闭包中,那么应该没有任何问题。
我不确定你要防范的是什么问题,但你也可能会使用委托(协议)而不是闭包。