Swift 如何从转义闭包中更改inout参数?

Swift 如何从转义闭包中更改inout参数?,swift,closures,Swift,Closures,我试图在转义闭包中修改函数的参数,如下所示: var completion = [()->Void]() func addCompletion(closure: @escaping ()->Void) { completion.append(closure) } func testAdd(v: inout Int) { addCompletion{ v = 1 // Compiler tells 'Escaping closure capture

我试图在转义闭包中修改函数的参数,如下所示:

var completion = [()->Void]()

func addCompletion(closure: @escaping ()->Void) {
    completion.append(closure)
}

func testAdd(v: inout Int) {
    addCompletion{
        v = 1  // Compiler tells 'Escaping closure captures 'inout' parameter 'v'
        print("hello1 \(v)")
    }
}

var x = 0
testAdd(v:&x)

for comp in completion {
    comp()
}

我想知道除了将其作为类对象转换为引用类型之外,是否还有其他方法可以让转义闭包更改周围变量(作为函数的inout参数)。

inout
被指定为具有“copy-in-copy-out”行为。调用函数时,会复制
x
的值。在函数体中,可以修改
x
的副本或其他内容。然后,当函数返回时,将再次复制副本,并将其分配给原始
x
。“参考电话”可以作为一种优化

这解释了为什么不能在转义闭包中修改
inout
参数。swift编译器不可能知道每个转义闭包何时返回,从而将修改后的值复制回来

您可以使用实际指针:

func testAdd(v: UnsafeMutablePointer<Int>) {
    addCompletion{
        v.pointee = 1 // you just need to change all references to "v" to "v.pointee"
        print("hello1 \(v.pointee)")
    }
}
您只需将呼叫者更改为:

testAdd { $0(&x) }

两个都有用,谢谢。在我看来,第二个解决方案是通过另一个闭包进行修改,它可以是引用类型,这确实需要我花相当长的时间来理解。
testAdd { $0(&x) }