2017-07-28 55 views
3

在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]

如何修改内部闭合原始变量()?

UPDATE:

其实我有一种解决方法通过将阵列到一个对象来处理这种情况,所以我可以通过引用传递该对象的函数,我们可以修改函数内的同一阵列实例。但我希望看到任何聪明的方法来存档,

回答

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)") 

:上面的示例是用于夫特3,其中inout参数不允许在封闭件被捕获。根据您的文章,您可能会使用较低版本的Swift,您可能可以使用inout而不是设置列表的可变副本var list = list。但是,逻辑非常相似。

欲了解更多信息,请查看Limiting inout capture to @noescape contexts在斯威夫特进化:

时关闭捕捉inout参数和逃避 及其外围方面斯威夫特的行为是混乱的常见原因。我们应该 禁止隐含捕获inout参数,但在@noescape 关闭。

+0

感谢您的回复,但有没有机会实现它,而无需访问函数内的任何实例变量?你可以把它当作一个静态函数 – Alan

+0

是的,我根据你的需要编辑我的答案。 – Lawliet

+0

谢谢,你的答案是一种获取数组的新副本的方法,我们可以在完成闭包中更新实例数组变量。但我想知道任何在传入函数后“直接”修改原始数组的机会。对于我在这个问题上的不好解释抱歉。我试过你的代码,全局'list'变量的结果仍然是[1,2,3] – Alan