I'm refactoring my app to use protocol and value type as much as possible, so I did a lot of experiments to understand how to use them properly. I find a pitfall when using value type and escaping closure together. See code below:
struct S {
var n: Int
var callback: (() -> Void)!
init(_ n: Int) {
self.n = n
self.callback = { [self] in
print(self.n)
}
}
}
var s1 = S(1)
s1.n = 2
s1.callback() // It outputs 1, not 2
The issue is different from the one that SE-0035 fixed. In SE-0035 case it's the escaping closure changes its copy. But in this case, it's the original copy that was changed but the escaping closure still uses the old copy.
If I understand it correctly, issue like this is almost unresolvable for value type, because there is no way to reference a single value. There have to be multiple copies of the value in above scenario and hence the inconsistency. If so, isn't value type and escaping closure a bad design that should be avoided? But I can't find any discussion about this. I wonder what's other people's experince on this? Sometimes I think it would be very helpful if Apple or someone with knowledge in this could write a book about value type and protocol programming best practice, the patterns and the scenarios to use them or to not use them.