在 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 ofinout
parameters except in@noescape
closures.
关于Swift 闭包通过引用捕获数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45366370/