This example is based on an example in the language reference (section Capture Lists):
class SimpleClass {
var value: Int = 0
}
var x = SimpleClass()
var y = SimpleClass()
let closure = { [x] in
print(x.value, y.value)
}
print(isKnownUniquelyReferenced(&x))
print(isKnownUniquelyReferenced(&y))
false
true
I expected both to be false because the closure strongly captures x and y. Why is the second true?
4 Likes
Nevin
2
x.value = 1
y.value = 2
closure() // prints "1 2"
x = SimpleClass()
y = SimpleClass()
x.value = 3
y.value = 4
closure() // prints "1 4"
I don’t know how it works under the hood, but the closure indeed treats x and y differently.
Explicit captures are always by-value captures, whereas implicit captures will be by-reference if the captured variable is a var. So there's indeed only one reference to the object stored in y (but two references to the variable y itself, one from the activation record for the top-level code and one from the closure), but there are two references to the object stored in x (one from x and one from the closure).
This is a real semantic difference: there are two ways to name the value currently in x, but only one to name the value currently in y.
5 Likes
Thank you. I get it now. It is good to know that explicit strong captures in capture lists are not identical to implicit ones.
I just tried explaining this myself, and ran into a brick wall with the terminology.
"Referring to a variable by value creates a new reference whereas referring to a variable by reference does NOT create a new reference." Very confusing! I think I have the picture in my head, but explaining it in non-jargon terms is impossible!
I think the important thing to understand about this example is that "x" is captured by value (because it's in the capture list) while "y" is captured by reference.
Nevin
6
It sounds like x “is” a reference to a class instance, and the closure captures—and thus copies—the value of x, which is to say a reference to a class instance. Thus there are 2 references to that class instance.
Similarly, y “is” also a reference to a class instance, but here the closure captures a reference to y. Thus, there is only one reference to the class instance referenced by y, and there is also a reference to that reference.
Is that right?
4 Likes