Swift:捕获逃脱被调用函数的闭包中的inout参数

我试着编写一个“编辑器”类,它可以保留对不同对象的属性的引用,以便以后进行变异。 我首先编写了编辑器类来接收一个用于读取的闭包,以及一个用于写入的闭包。 这很有效。 然后我尝试通过(inout)引用传递有问题的参数,然后从中生成getter / setter对。 这没用。 Swift文档确实说(释义)Swift确定何时复制,何时不复制。 我认为我反对这种限制的不可预测性,但我认为我提出的问题是一样的。

或者,是否可以获得个人吸气剂和定位器的咖喱function?

我的代码是:

class SomeModel : Printable { var a:String init(a:String) { self.a = a } var description:String { return "\(self.a)" } } class Editor { var getter:()-> String var setter:(String)->() init(getter:()-> String, setter:(String)->()) { self.getter = getter self.setter = setter } convenience init(inout bindTo:String) { self.init( getter:{ return bindTo }, setter: { v in bindTo = v }) } func read() -> String { return self.getter() } func write(value:String) { self.setter(value) } } func testBindTo() { var readModel = SomeModel(a:"Did not capture by reference"); var bindForReading = Editor(bindTo: &readModel.a) readModel.a = "captured by reference!" println(bindForReading.read()) var writeModel = SomeModel(a:"Did not capture by reference"); var bindForWriting = Editor(bindTo: &writeModel.a) bindForWriting.write("captured by reference") println(writeModel) } testBindTo() func testExplicitGetterSetter() { var readModel = SomeModel(a:"Did not capture by reference"); var bindForReading = Editor( getter: { readModel.a }, setter: { v in readModel.a = v }) readModel.a = "captured by reference!" println(bindForReading.read()) var writeModel = SomeModel(a:"Did not capture by reference"); var bindForWriting = Editor( getter: { writeModel.a }, setter: { v in writeModel.a = v }) bindForWriting.write("captured by reference") println(writeModel) } testExplicitGetterSetter() 

结果是:

 Did not capture by reference Did not capture by reference captured by reference! captured by reference 

谢谢!

我不认为这是可能的。 如果你想一想,它应该是不可能的,因为它会超级不安全。

因为闭包可以比它们创建的范围更长,所以捕获的变量必须与块一起存储。 但是为了能够分配给捕获的变量并在捕获它的(一个或多个)块和原始范围之间共享该变量的状态,这些块不能只捕获变量的值(将创建变量的独立副本),但捕获一种对共享副本的“引用”。 这意味着必须专门存储由块捕获的可分配变量。 在Objective-C中,这是用__block声明的。 在Swift中,这个__block行为是隐含的。

但是,为了使块能够在函数调用者的作用域中看到修改inout变量(可能在稍后的时间),这意味着调用者作用域中传递的变量也需要以这样的方式存储:可以比堆栈帧寿命更长。 但调用函数不知道这一点。 根据被调用函数的类型,它所知道的是它的一个参数是inout ; 它不知道该函数计划捕获块中的inout变量。 所以它不知道为这个传递的变量准备这个__block存储。