What is the idiomatically correct way to mutate a dictionary/other collection asynchronously in Swift?
The following type of situation often arises while coding:
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)
}
Here, I am loading some data asynchronously and adding it to a collection passed in as a parameter.
However, this code does not compile in Swift because of the copy semantics of inout
.
I have thought of two workarounds to this problem:
- Wrap the dictionary in a class, and pass this class to the function instead. Then I can mutate the class, as it is not a value type.
- Use unsafe pointers
Which is the idiomatically correct way to do this?
I saw that there is some discussion on this topic in this question: Inout parameter in async callback does not work as expected. However, none of the answers focused on how to actually solve the problem, only why the code as it is now doesn't work.