Consider the following example given below:
protocol Something: AnyObject {
func f()
}
class A {
unowned var something1: Something!
weak var something2: Something!
func f() {
something1.f()
something2.f()
}
}
What is the difference between type of something1
and something2
?
Quick summary:
weak var something2: Something!
is bad since you are effectively force-unwrapping a variable that is assumed (viaweak
) to benil
at some future time after being set.unowned var something1: Something!
is better. The use ofunowned
is only to be used when it is assumed that the variable reference will remain valid longer than the lifetime of the variable. Making it implicitly unwrapped assumes it will never becomenil
once given a value.Details. Let's break this down into parts.
What's the difference between
weak
andunowned
?From the ARC chapter in the Swift book - Weak References:
From the ARC chapter in the Swift book - Unowned References:
From the ARC chapter in the Swift book - Unowned Optionals:
What is an implicitly unwrapped optional (IUO)?
From the Basics chapter in the Swift book - Implicitly Unwrapped Optionals:
What does this mean for
weak var something2: Something!
?Based on the description of
weak
and ofIUO
, having a variable that is bothweak
andIUO
is a contradiction.weak
is assumed that it will be set tonil
at some point after being set.IUO
is assumed that it will not be nil once given a value.So if you have
weak var something2: Something!
and later you trysomething2.f()
, your program will crash ifsomething2
has been set tonil
either directly or due to ARC setting it tonil
due to the reference being deallocated.The use of the
IUO
is your way of telling the compiler "trust me, it will never be nil". But the use ofweak
is telling the compiler "careful, it might be nil". That's a marriage doomed for a divorce.What does this mean for
unowned var something1: Something!
?Unlike
weak
,unowned
variables can be either optional or non-optional. AnIUO
is an optional but it precludes the need to handle it like an optional. So anunowned IUO
is an optional.Based on the description of
unowned
and ofIUO
, having a variable that is bothunowned
andIUO
is a bit redundant but useful. Making a variableunowned
means you ensure it maintains a non-nil value once set.IUO
is assumed that it will not be nil once given a value. So both have the same goal.Being
unowned
, it doesn't hold a strong reference so it has that benefit ofweak
. But being an optionalunowned
means you are responsible to ensure it maintains a reference to a valid object or is explicitly set tonil
(since ARC will not do so for you). BeingIUO
, you are assuming it will never benil
so you don't have to add needed syntax normally used with optionals.So if you have
unowned var something1: Something!
and later you trysomething1.f()
, your program will crash ifsomething1
references a deallocated object or if it has explicitly been set tonil
.Summary:
Don't use a
weak var something: Something!
. It's a crash waiting to happen.Use
unowned var something: Something
if you can set the value in an initializer or declared scope, you don't want a strong reference, and the reference will remain valid once set.Use
unowned var something: Something!
if you can't set the value in an initializer or declared scope, you won't attempt to access the variable until set, you don't want a strong reference, and the reference will remain valid once the initial value is set.Use
unowned var something: Something?
if you don't want a strong reference, the reference will remain valid while set, and you may want to explicitly set the value tonil
at some point.Keep in mind that all uses of
unowned
can cause a crash if the referenced instance has been deallocated. So only useunowned
when you know that won't happen.