Swift指示保留闭包参数

时间:2016-08-17 23:16:55

标签: swift closures automatic-ref-counting

有没有办法向"客户"一个特定的方法,将保留一个闭包参数?

例如,拥有以下代码:

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的定义中,它向客户提供了关于弱化以避免泄漏的需要

2 个答案:

答案 0 :(得分:2)

闭包参数是否转义或非转义是调用者是否可以保留的一些指示。特别是,函数调用不能 -escaping闭包参数

SE-0103,非转义闭包(当前标记为@noescape)将成为Swift 3中的默认值,如果要保存闭包,则必须编写@escaping ,所以这样的情况会变得更加明显。

否则,没有语言功能可以帮助您。您必须使用API​​设计和文档解决此问题。如果它类似于处理程序,我会推荐一个属性obj.handler = { ... }或类似obj.setHandler({ ... })obj.addHandler({ ... })的方法。这样,在阅读代码时,您可以轻松地告知由于=setadd而正在保存闭包。

(实际上,在确定是否警告用户关于保留周期时编译Obj-C,Clang explicitly looks for methods named set...: or add...:时。将来可能会向Swift编译器添加类似的诊断。)

答案 1 :(得分:0)

对于特定情况,你提出的闭包本身是唯一可以保留的东西,所以如果你在调用时正确地将[弱自我]添加到你的闭包中,那么应该没有任何问题。

我不确定你要防范的是什么问题,但你也可能会使用委托(协议)而不是闭包。