Swift 闭包通过引用捕获数组

标签 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]

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

更新:

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

最佳答案

要从闭包中获取变量转义,您需要@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 而不是设置 list 的可变副本:var列表 = 列表。但是,逻辑非常相似。

有关详细信息,请查看 Limiting inout capture to @noescape contexts 在 Swift 演进中:

Swift's behavior when closures capture inout parameters and escape their enclosing context is a common source of confusion. We should disallow implicit capture of inout parameters except in @noescape closures.

关于Swift 闭包通过引用捕获数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45366370/

相关文章:

swift - 在自定义 tableView 单元格上使用 contentView 属性(作为标题传递)如何防止它使自定义属性无效?

医疗保健应用程序的 iOS 后台执行

ios - 在 UITableViewDelegate 扩展中使用未解析的标识符

javascript - Three.js 根据名称失败加载纹理

functional-programming - 闭包的确切定义是什么?

c++ - Qt - 这是通过引用传递吗?

c# - 采用 ref 类型并对其进行操作的 void 方法与将 ref 返回到同一对象的方法之间有什么区别

ios - CoreBluetooth 广告未启动

java - 关闭和回调

java - 如何阻止对一个 ArrayList 中的对象的修改同时修改另一个 ArrayList 中的同一对象