gpt4 book ai didi

ios - Swift:在转义被调用函数的闭包中捕获inout参数

转载 作者:搜寻专家 更新时间:2023-10-31 08:27:00 24 4
gpt4 key购买 nike

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

或者,是否可以为单独的 getter 和 setter 获取柯里化(Currying)函数?

我的代码是:

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

谢谢!

最佳答案

我认为这是不可能的。而且它不应该是可能的,如果你考虑一下,因为它会非常不安全。

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

然而,为了让 block 修改 inout 变量(可能在稍后的时间),因为它在函数调用者的范围内看到,这意味着调用者范围内的传递变量还需要以一种可以比堆栈框架更长寿的方式存储。但是调用函数并不知道这一点。它从被调用函数的类型中知道的只是它的一个参数是inout;它不知道该函数计划在 block 中捕获该 inout 变量。所以它不知道为这个传递的变量准备这个__block 存储。

关于ios - Swift:在转义被调用函数的闭包中捕获inout参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30020250/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com