在 Swift 中异步改变字典/其他集合的惯用正确方法是什么?
编码时经常出现以下类型的情况:
func loadData(key: String, dict: inout [String: String]) {
// Load some data. Use DispatchQueue to simulate async request
DispatchQueue.main.async {
dict[key] = "loadedData"
}
}
var dict = [String:String]()
for x in ["a", "b", "c"] {
loadData(key: x, dict: &dict)
}
在这里,我异步加载一些数据并将其添加到作为参数传入的集合中。
但是,由于 inout
的复制语义,此代码无法在 Swift 中编译。
我想到了解决这个问题的两种方法:
- 将字典包装在一个类中,并将该类传递给函数。然后我可以改变类,因为它不是值类型。
- 使用不安全指针
执行此操作的惯用正确方法是什么?
我看到这个问题中有一些关于这个主题的讨论:Inout parameter in async callback does not work as expected 。然而,没有一个答案集中于如何实际解决问题,只关注为什么现在的代码不起作用。
最佳答案
这个(黑客)似乎有效:
func loadData(key: String, applyChanges: @escaping ((inout [String: String]) -> Void) -> Void) {
DispatchQueue.main.async {
applyChanges { dict in
dict[key] = "loadedData"
}
}
}
...
for x in ["a", "b", "c"] {
loadData(key: x) { $0(&dict) }
}
虽然不惯用...我想说这里要做的惯用做法是不异步改变事物。您始终可以将想要对完成处理程序中的集合进行的更改返回。对于字典,这可能是另一个字典,然后您将其与原始字典合并
。
关于ios - 在 Swift 中异步改变集合的惯用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62657685/