In Swift, we have normal default typing
we have weak typing
and we have unowned typing
(So: by corollary: the one and only time you can use "unowned" is if you "absolutely know" the object will never become nil.)
Now: it seems to me that the following sentence is absolutely true ... and by absolutely I mean, really, truly, absolutely, down to the deepest possible philosophical concerns true...
"The only difference between unowned and weak, is performance. Since unowned has no checking, it is faster. There is absolutely no other difference."
and hence the logical corollary:
"There is, absolutely, no reason to use unowned, other than if the extra performance over weak is needed."
(Aside - the only other difference I can think of is in the self-documenting sense. If I use unowned, it cues my fellow developers to certain things; let us set aside that issue for now.)
So my question is straightforward, very exact, very specific: are the bold sentences above "true" (in the "utterly, very, spectacularly" true sense of true).
I agree with Yannick. Your bold statements are not correct. An unowned reference must be valid for its lifetime. In an -Ounchecked
program, failure to maintain this precondition is undefined behavior. I don't mean "it crashes." I mean it is not a well-formed program; it is undefined what it does. A weak reference cannot generate undefined behavior due to its release, even under -Ounchecked
.
Using unowned
is a statement by the programmer that the reference will be valid over its entire lifetime. That's not even something Type!
asserts. !
types just assert that the reference will be valid at the point that it is accessed. That's why you can't test x == nil
on an unowned. It is not optional. It's not "optional in disguise" (like Type!
). It must always be valid.
Unlike a weak reference, however, an unowned reference is used when the other instance has the same lifetime or a longer lifetime. ... An unowned reference is expected to always have a value. —— [The Swift Programming Language]
So to your "deepest possible philosophical," unowned includes a precondition that does not exist in weak. This precondition exists outside the program, and must be proven by programmer, not the compiler, in order to ensure a well-formed program.
To whether there is a reason to use unowned
, there certainly is if we're taking an absolutest stance (as in your question). It is the tightest type in cases where the precondition is known to be true. weak
is a weaker type than unowned
; it expresses fewer preconditions. Good type theory encourages us to use the strongest (most restrictive; fewest legal values) types we can, and unowned
is a stronger type than weak
.
In a non-absolutist ("practical") sense, the result of picking a stronger type is simpler code. When you use weak
, you have to constantly re-assert the precondition that it is not nil
every time you use it and handle the cases where it is (possibly inserting fatalError
which just reinvents unowned
with more work). Using unowned
lets you assert this precondition one time. This creates simpler, more correct code. I've never used unowned
for speed. I've always used it to avoid answering over and over again "but what if it's nil?" in code where it must never be nil.