I don't know whether there's official documentation that gets to the level of implementation detail you might be interested in, but the Weak References section of the Automatic Reference Counting page of The Swift Programming Language book might get you part-way.
A few posts from the Weak Let pitch (which has since been accepted and implemented) that may also be instructive in forming a mental model:
- [Pitch] Weak let - #9 by John_McCall
- [Pitch] Weak let - #11 by mpangburn
- [Pitch] Weak let - #15 by John_McCall
tl;dr: weak references are a special type of value that at read time either produces a value if the referenced object still exists, or returns nil; this unwrapping behavior is consistent in all Swift contexts.
To that end, in this example:
the compiler and optimizer are, to the best of my knowledge, not allowed to hoist the self check outside of the loop in the general case, because it changes the semantics of the loop, same as above:
- Setting
self.lastStatemay have side effects which would leadselfto be deallocated, normally breaking out of the loop early; ifselfis unwrapped outside of the loop and retained, it may unexpectedly loop over all ofstates - In the absence of side-effects,
statesmay be an extremely large (or even infinite) sequence of values such that hoisting the check outside the loop might have a significant performance impact (or even turn what is normally a terminating loop into an infinite loop) - The iteration itself may have side effects: types'
SequenceandIteratorProtocolconformances can run arbitrary code, such that terminating at different points may have visible side effects
It's possible that, if the optimizer has enough static knowledge about both self and states that it can prove none of these are possible, and therefore the check can be hoisted out, but I'd wager this'd be an expensive and invasive check for little potential win. (And, to the best of my knowledge, optimizations like this are largely implementation detail, and not documented publicly.)