How do I use weak and unowned references correctly in Swift?

In Swift, memory management is an essential aspect of programming, and understanding how to use weak and unowned references is crucial to prevent retain cycles and memory leaks. Both weak and unowned references are used in situations where you want to avoid strong reference cycles, particularly in the case of closures and parent-child relationships between classes.

Weak References

A weak reference allows one object to refer to another without keeping a strong hold on it. If the object being referenced is deallocated, the weak reference is automatically set to nil. This is useful in cases where you want to avoid strong reference cycles, for example, in delegate patterns.

Unowned References

An unowned reference is similar to a weak reference, but it is expected that the referenced object will always exist as long as the unowned reference is being accessed. Unowned references are used when you know that the referenced object cannot be nil at the point of access.

Example

class Person { var name: String var pet: Pet? init(name: String) { self.name = name } } class Pet { var name: String weak var owner: Person? init(name: String) { self.name = name } } let john = Person(name: "John") let dog = Pet(name: "Rex") john.pet = dog dog.owner = john print(john.pet?.name) // Output: Rex print(dog.owner?.name) // Output: John

Swift weak references unowned references memory management retain cycles