Does Swift enum retain its associated value
Table of Contents
As an iOS developer, enum with associated values is one my of my favorite language feature, and it is also a secret behind Optional, another language feature I love. I recently wonder which type of reference, strong and weak, does enum hold its associated value.
You can define Swift enumerations to store associated values of any given type, and the value types can be different for each case of the enumeration if needed.
Excerpt from Swift documentation.
I found on the Swift documentation that enumerations store the value, but it doesn't mention it is a weak or strong reference.
Weak or Strong
We can tell that enum holds a strong reference to its associated values based on the fact that Swift Optional implements using enum, and it can hold any object reference without releasing it.
Here is an example use of Swift Optional.
let user: User? = Optional.some(User()) // <1>
if let user = user { // <2>
print("It's alive")
}
1 Enum Optional with an associated value of User()
.
2 Check whether user
is nil
and print "It's alive" if it is not.
If the enum holds a weak reference, the User()
object will get released because nobody holds it except the optional enum. We won't see anything print in the debug console. If enum holds a strong reference, we will see "It's alive" print in the console.
You should be able to guess the result without running it since we use something like this all the time. And yes, "It's alive" will be printed, which confirms that ** enum retains its associated value**.
You can easily support sarunw.com by checking out this sponsor.
AI Grammar: Correct grammar, spell check, check punctuation, and parphrase.
Can we make retain cycle with an enum
Can enum cause a retain cycle? This question was popping up after I realized that enum holds a strong reference to its associated value. It definitely should, but I want to be sure, so I make a little experiment.
First, we create a LoginStatus
enum. It contains two cases, guest
and loggedIn
with User
as an associated value.
enum LoginStatus {
case loggedIn(User)
case guest
}
Then we create a User
class with a LoginStatus
as a property.
class User {
var status: LoginStatus = .guest
deinit {
print("deinit user") // <1>
}
}
1 We have a deinitializer to observe whether the object gets release or not.
Experiment 1: Guest user
In this first example, I want to show that an object with no reference will be released. We create a local variable user
in viewDidLoad
. Run the app, and you should see "deinit user" print in the debug console. No one holds or retains our user object, so it gets released after the method ended.
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let user = User()
}
}
The result, "deinit user" printed in the console:
deinit user
Experiment 2: Logged in user
In this experiment, we want to create a retain cycle with enum. All the setups are the same as experiment 1, but this time, we set user.status
to .loggedIn(user)
. This should create a retain cycle since the user holds a strong reference of status
. And status
also holds a strong reference back to user
in the form of associated value in the enum, .loggedIn(user)
.
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let user = User()
user.status = .loggedIn(user) // <1>
}
}
1 We create a retain cycle by make status
hold a strong reference back to user
.
Run the app, and you shouldn't see any message in the debug console. The retain cycle has formed, and our user object lives happily ever after in the memory.
You can easily support sarunw.com by checking out this sponsor.
AI Grammar: Correct grammar, spell check, check punctuation, and parphrase.
Conclusion
Enum holds a strong reference to its associated value is an obvious fact that I always overlook. I was never aware that I could cause retain cycle by using an enumeration. I would say it is not likely to happen in our day-to-day tasks, but you should aware that it can happen.
Read more article about Swift, Enum, or see all available topic
Enjoy the read?
If you enjoy this article, you can subscribe to the weekly newsletter.
Every Friday, you'll get a quick recap of all articles and tips posted on this site. No strings attached. Unsubscribe anytime.
Feel free to follow me on Twitter and ask your questions related to this post. Thanks for reading and see you next time.
If you enjoy my writing, please check out my Patreon https://www.patreon.com/sarunw and become my supporter. Sharing the article is also greatly appreciated.
Become a patron Buy me a coffee Tweet ShareRecord iOS Simulator video as mp4 and GIF with Xcode
Xcode 12.5 brings many great updates and features. One of them is the ability to record a video of the app directly from the Simulator app.