An inout
argument isn't a reference to a value type – it's simply a shadow copy of that value type, that is written back to the caller's value when the function returns.
What's happening in your code is that your inout
variable is escaping the lifetime of the function (by being captured in a closure that is then stored) – meaning that any changes to the inout
variable after the function has returned will never be reflected outside that closure.
Due to this common misconception about inout
arguments, there has been a Swift Evolution proposal for only allowing inout
arguments to be captured by @noescape
closures. As of Swift 3, your current code will no longer compile.
If you really need to be passing around references in your code – then you should be using reference types (make your Model
a class
). Although I suspect that you'll probably be able to refactor your logic to avoid passing around references in the first place (however without seeing your actual code, it's impossible to advise).
(Edit: Since posting this answer, inout
parameters can now be compiled as a pass-by-reference, which can be seen by looking at the SIL or IR emitted. However you are unable to treat them as such due to the fact that there's no guarantee whatsoever that the caller's value will remain valid after the function call.)