Swift闭包捕获数组通过引用

时间:2017-07-28 06:31:16

标签: swift closures pass-by-reference pass-by-value inout

在Swift集合中,默认情况下是按值传递的,我们可以使用inout使它在函数参数中通过引用传递,但是我们如何在闭包捕获变量中执行呢?

var list = [1, 2, 3]
func edit(inout list: [Int]) {
    list.append(4)
    dispatch_async(dispatch_get_main_queue()) {
        list.append(5)
    }
}
edit(&list)
...// after dispatch_async was executed 
NSLog("\(list)")

结果将是[1,2,3,4]

如何修改闭包内的原始变量()?

更新

实际上我有一个解决方法来处理这种情况,方法是将数组放入一个对象中,这样我就可以通过引用将这个对象传递给函数,我们可以在函数内部修改相同的数组实例。但我希望看到任何聪明的方式来存档

1 个答案:

答案 0 :(得分:2)

要从闭包中获取变量,需要@escaping,请检查this。解决方法是将完成函数作为参数而不是inout变量。

class MyClass {
    static func edit(_ list: [Int], _ completion: @escaping ([Int]) -> ()) {
        var list = list
        list.append(4)
        DispatchQueue.main.async() {
            list.append(5)
            completion(list)
        }
    }
}

var myList = [1, 2, 3]
MyClass.edit(myList) { (list) in
    myList = list
    print("My list after editing: \(myList)")
}
print("My list without editing: \(myList)")

注意:上面的示例适用于Swift 3,其中不允许在闭包中捕获inout个参数。根据您的帖子,您可能正在使用较低版本的Swift,您可以使用inout而不是设置列表的可变副本var list = list。但是,逻辑非常相似。

有关详细信息,请查看Swift evolution中的 Limiting inout capture to @noescape contexts

  

当闭包捕获inout参数并逃脱时,Swift的行为   它们的封闭背景是混乱的常见原因。我们应该   禁止隐含捕获inout参数,@noescape除外   闭包。

相关问题