Why iOS Developers overlook the usefulness of unowned
Published: 2024-02-14 01:23:47

Most iOS Developers I’ve talked to about unowned variables disregard its specific usefulness. Even worse, they just default to weak without a justified reason. I think this is because it’s not commonly used in our day-to-day development. But if you spend some time digging into Swift’s own documentation around the topic and doing your own hands-on tinkering, you’ll quickly notice what makes unowned important and realize the distinction between weak and owned.

What makes unowned important is that unlike weak variables, unowned variables can be declared as non-optionals. That means we are responsible for assigning them a value during initialization. Which tells us precisely their usefulness, that we must use unowned when we need to establish a tightly coupled relationship between two objects. For instance, when establishing relationships between a customer and a credit card object, we instinctively know that a customer may or may not own a credit card, but a credit card must always be tied to a customer. If it doesn’t have a customer, well, it’s not a credit card, is it? It’s just a piece of plastic.

Since all weak properties are optional, you can create a credit card without a customer, and this is precisely what you want to avoid. The way to avoid it is by using a non-optional unowned property that enforces the relationship safely.

Here’s an example to demonstrate visually unowned’s usefulness:

**Weak:**
As you can see, if we use weak, we can initialize a credit card with or without a customer. While this would still work, it’s not explicit and we should aim to be explicit when possible. I assume that is why the Swift creators included unowned in the first place.

```Swift
class Customer {
    let name: String
    var card: CreditCard?
    init(name: String) {
        self.name = name
    }
    deinit { print("\(name) is being deinitialized") }
}
class CreditCard {
    let number: UInt64
    weak var customer: Customer?
    init(number: UInt64, customer: Customer) {
        self.number = number
        self.customer = customer
    }
    deinit { print("Card #\(number) is being deinitialized") }
}
var john: Customer?
john = Customer(name: "John Appleseed")
john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)
```

**Unowned:**
Here, on the other hand, since we’re using a non-optional unowned, we are required to include the credit card in the initialization. Now by simply looking at this class init method, it’s clear that a credit card must always have a customer, since it’s not possible to create a credit card without one. That’s a level of clarity we can’t achieve if we use a weak variable.

```Swift
class Customer {
    let name: String
    var card: CreditCard?
    init(name: String) {
        self.name = name
    }
    deinit { print("\(name) is being deinitialized") }
}
class CreditCard {
    let number: UInt64
    unowned var customer: Customer
    init(number: UInt64, customer: Customer) {
        self.number = number
        self.customer = customer
    }
    deinit { print("Card #\(number) is being deinitialized") }
}
var john: Customer?
john = Customer(name: "John Appleseed")
john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)
```

Here’s a framework I use that helps me remember the functionality of each keyword, and helps me identify in which situations they’re most applicable.

**Summary**
Today we explored the specific difference between unowned and weak. We highlighted the usefulness of using unowned as “clarity” in establishing a reference back to the parent object while avoiding a strong reference cycle, which is the primary purpose of both weak and unowned.