在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]
如何修改闭包内的原始变量()?
更新
实际上我有一个解决方法来处理这种情况,方法是将数组放入一个对象中,这样我就可以通过引用将这个对象传递给函数,我们可以在函数内部修改相同的数组实例。但我希望看到任何聪明的方式来存档
答案 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
除外 闭包。