Sitemap

๐— ๐—ฎ๐˜€๐˜๐—ฒ๐—ฟ๐—ถ๐—ป๐—ด ๐—ฆ๐˜„๐—ถ๐—ณ๐˜ ๐— ๐—ฒ๐—บ๐—ผ๐—ฟ๐˜† ๐— ๐—ฎ๐—ป๐—ฎ๐—ด๐—ฒ๐—บ๐—ฒ๐—ป๐˜: ๐—ฆ๐˜๐—ฟ๐—ผ๐—ป๐—ด, ๐—ช๐—ฒ๐—ฎ๐—ธ & ๐—จ๐—ป๐—ผ๐˜„๐—ป๐—ฒ๐—ฑ ๐—ฅ๐—ฒ๐—ณ๐—ฒ๐—ฟ๐—ฒ๐—ป๐—ฐ๐—ฒ๐˜€

3 min readMar 12, 2025

--

Understanding how references work in Swift is key to preventing retain cycles and memory leaks. Below are simple, real-world examples for each reference type โ€” complete with diagrams, code samples, and a comparison table.

1. ๐—ฆ๐˜๐—ฟ๐—ผ๐—ป๐—ด ๐—ฅ๐—ฒ๐—ณ๐—ฒ๐—ฟ๐—ฒ๐—ป๐—ฐ๐—ฒ (Default)

Real-World Example:
Imagine a Book in your personal library. The library holds a strong reference to the Book, ensuring it stays in memory until you remove it.

Diagram:

myBook (strong) ---> Book instance

Code Example:

class Book {
let title: String
init(title: String) {
self.title = title
print("Book '\(title)' is created")
}
deinit {
print("Book '\(title)' is deallocated")
}
}

var myBook: Book? = Book(title: "Swift Programming")
// 'myBook' holds a strong reference to the Book.
myBook = nil // The Book is deallocated.

Explanation:
A strong reference increases the reference count. As long as the variable exists, the object remains in memory.

2. ๐—ช๐—ฒ๐—ฎ๐—ธ ๐—ฅ๐—ฒ๐—ณ๐—ฒ๐—ฟ๐—ฒ๐—ป๐—ฐ๐—ฒ

Real-World Example:
Consider a Parent-Child relationship. A parent holds a strong reference to the child, while the childโ€™s reference back to the parent is weak โ€” preventing a retain cycle.

Get Bala Baskar Bollisettyโ€™s stories inย yourย inbox

Join Medium for free to get updates fromย thisย writer.

Diagram:

Parent --(strong)--> Child  
Child --(weak)--> Parent

Code Example:

class Parent {
var child: Child?
init() { print("Parent created") }
deinit { print("Parent deallocated") }
}

class Child {
// The child's reference to its parent is weak.
weak var parent: Parent?
init() { print("Child created") }
deinit { print("Child deallocated") }
}

var mom: Parent? = Parent()
var kid: Child? = Child()

mom?.child = kid // Strong reference from Parent to Child.
kid?.parent = mom // Weak reference from Child to Parent.

// Break both references.
mom = nil
kid = nil

Explanation:
A weak reference does not increase the reference count and automatically becomes nil when the object is deallocated, effectively breaking the cycle.

3. ๐—จ๐—ป๐—ผ๐˜„๐—ป๐—ฒ๐—ฑ ๐—ฅ๐—ฒ๐—ณ๐—ฒ๐—ฟ๐—ฒ๐—ป๐—ฐ๐—ฒ

Real-World Example:
Think of a Car and its Engine. A car always has an engine. The car holds a strong reference to its engine, while the engine uses an unowned reference back to the car โ€” assuming the car will always exist during the engineโ€™s lifetime.

Diagram:

Car --(strong)--> Engine  
Engine --(unowned)--> Car

Code Example:

class Car {
let model: String
var engine: Engine?

init(model: String) {
self.model = model
print("Car \(model) is created")
}

deinit {
print("Car \(model) is deallocated")
}
}

class Engine {
let serialNumber: String
// Unowned because the engine always belongs to a Car.
unowned let car: Car

init(serialNumber: String, car: Car) {
self.serialNumber = serialNumber
self.car = car
print("Engine \(serialNumber) is created for \(car.model)")
}

deinit {
print("Engine \(serialNumber) is deallocated")
}
}

// Example usage:
var myCar: Car? = Car(model: "Toyota Camry")
myCar?.engine = Engine(serialNumber: "ENG12345", car: myCar!)
// When 'myCar' is set to nil, both Car and Engine are deallocated.
myCar = nil

Explanation:
An unowned reference does not increase the reference count and cannot be nil. Itโ€™s used when youโ€™re certain the referenced object will outlive the reference.

๐—ž๐—ฒ๐˜† ๐——๐—ถ๐—ณ๐—ณ๐—ฒ๐—ฟ๐—ฒ๐—ป๐—ฐ๐—ฒ๐˜€ ๐—•๐—ฒ๐˜๐˜„๐—ฒ๐—ฒ๐—ป ๐—ฆ๐˜๐—ฟ๐—ผ๐—ป๐—ด, ๐—ช๐—ฒ๐—ฎ๐—ธ & ๐—จ๐—ป๐—ผ๐˜„๐—ป๐—ฒ๐—ฑ ๐—ฅ๐—ฒ๐—ณ๐—ฒ๐—ฟ๐—ฒ๐—ป๐—ฐ๐—ฒ๐˜€

+--------------------+---------------------------+---------------------+--------------------------------------------------+
| Reference Type | Increases Reference Count | Optional? | When to Use |
+--------------------+---------------------------+---------------------+--------------------------------------------------+
| Strong | Yes | N/A (default type) | When you "own" the object to keep it alive |
| Weak | No | Yes (auto nil) | When the object might be deallocated |
| Unowned | No | No | When the object is guaranteed to exist |
| | | | (e.g., a Car's engine always exists with a Car) |
+--------------------+---------------------------+---------------------+--------------------------------------------------+

๐—ž๐—ฒ๐˜† ๐—ง๐—ฎ๐—ธ๐—ฒ๐—ฎ๐˜„๐—ฎ๐˜†๐˜€

โ€ข Strong Reference: Keeps the object alive as long as the reference exists.
โ€ข Weak Reference: Prevents retain cycles by not increasing the reference count; automatically becomes nil when the object is deallocated.
โ€ข Unowned Reference: Assumes the object will always be available; ideal for relationships where the referenced object must persist.

Using the correct reference type helps manage memory efficiently and ensures your Swift applications run smoothly.

#Swift #iOSDevelopment #MemoryManagement #RetainCycles #CodingTips

--

--