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 benilat some future time after being set.unowned var something1: Something!is better. The use ofunownedis 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 becomenilonce given a value.Details. Let's break this down into parts.
What's the difference between
weakandunowned?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
weakand ofIUO, having a variable that is bothweakandIUOis a contradiction.weakis assumed that it will be set tonilat some point after being set.IUOis 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 ifsomething2has been set tonileither directly or due to ARC setting it tonildue to the reference being deallocated.The use of the
IUOis your way of telling the compiler "trust me, it will never be nil". But the use ofweakis 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,unownedvariables can be either optional or non-optional. AnIUOis an optional but it precludes the need to handle it like an optional. So anunowned IUOis an optional.Based on the description of
unownedand ofIUO, having a variable that is bothunownedandIUOis a bit redundant but useful. Making a variableunownedmeans you ensure it maintains a non-nil value once set.IUOis 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 optionalunownedmeans 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 benilso 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 ifsomething1references 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: Somethingif 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 tonilat some point.Keep in mind that all uses of
unownedcan cause a crash if the referenced instance has been deallocated. So only useunownedwhen you know that won't happen.