I\'m trying to insert functions with inout parameter to append data received from async callback to an outside array. However, it does not work. And I tried eve
Sad to say, modifying inout parameter in async-callback is meaningless.
From the official document:
Parameters can provide default values to simplify function calls and can be passed as in-out parameters, which modify a passed variable once the function has completed its execution.
...
An in-out parameter has a value that is passed in to the function, is modified by the function, and is passed back out of the function to replace the original value.
Semantically, in-out parameter is not "call-by-reference", but "call-by-copy-restore".
In your case, counter is write-backed only when getOneUserApiData() returns, not in dataTaskWithRequest() callback.
Here is what happened in your code
getOneUserApiData() call, the value of counter 0 copied to c1c1dataTaskWithRequest()getOneUserApiData returns, and the value of - unmodified - c1 is write-backed to counterc2, c3, c4 ...c1 is incremented.c2 is incremented.c3 is incremented.c4 is incremented.As a result counter is unmodified :(
Detailed explaination
Normally, in-out parameter is passed by reference, but it's just a result of compiler optimization. When closure captures inout parameter, "pass-by-reference" is not safe, because the compiler cannot guarantee the lifetime of the original value. For example, consider the following code:
func foo() -> () -> Void {
var i = 0
return bar(&i)
}
func bar(inout x:Int) -> () -> Void {
return {
x++
return
}
}
let closure = foo()
closure()
In this code, var i is freed when foo() returns. If x is a reference to i, x++ causes access violation. To prevent such race condition, Swift adopts "call-by-copy-restore" strategy here.