2016-08-17 51 views
3

是否有任何方式向特定方法的“客户端”指示闭包参数将被保留?Swift指示保留了闭包参数

例如,具有下面的代码:

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

闭合参数是转义还是非转义对于调用者是否可以保留。特别是,一个 - 转义闭包参数不能保留一个函数调用。

SE-0103,不逃避关闭(当前标记@noescape)将成为斯威夫特3默认的,你得写@escaping如果你想保存关闭,所以这样的情况下将变的更为明显。

否则,没有语言功能来帮助你在这里。你必须用API设计和文档来解决这个问题。如果它像处理程序那样,我会推荐一个属性,obj.handler = { ... }或者像obj.setHandler({ ... })obj.addHandler({ ... })这样的方法。这样一来,在阅读代码时,您可以很容易地知道由于=setadd而正在保存关闭。

(事实上,编译的OBJ-C时,锵explicitly looks for methods named set...: or add...:确定何时是否警告用户关于保留周期。这是可能的类似的诊断可以被添加到所述夫特编译器在未来。)

0

随着你提出闭包本身的唯一情况是唯一将被保留的情况,所以如果在你打电话时正确添加[弱自己]到闭包,那就不应该有任何问题。

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