Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

Swift Dictionary

  1. Home
  2. Swift Dictionary
  3. ARC / Strong References / Retain Cycles

ARC / Strong References / Retain Cycles

Swift manages memory automatically using ARC (Automatic Reference Counting). An instance of a class is kept in memory as long as there is at least one strong reference to it.

Syntax

// Strong reference (default)
var a: MyClass? = MyClass()  // Reference count: 1
var b = a                    // Reference count: 2
a = nil                      // Reference count: 1 (b still holds it)
b = nil                      // Reference count: 0 → released

// Pattern that causes a retain cycle
class A {
    var b: B?   // A holds a strong reference to B
}
class B {
    var a: A?   // B holds a strong reference to A → retain cycle!
}

Terminology

TermDescription
ARC (Automatic Reference Counting)Automatically tracks the number of references to a class instance and frees its memory when the count reaches zero.
Strong referenceThe default type of reference. Increments the reference count.
Reference countThe number of references pointing to an instance. When it reaches zero, the instance is deallocated.
Retain cycleA situation where two instances hold strong references to each other, preventing the reference count from ever reaching zero and causing a memory leak.

Sample Code

class Person {
    let name: String

    init(name: String) {
        self.name = name
        print("\(name) was created")
    }

    deinit {
        print("\(name) was released")
    }
}

// Basic strong reference behavior
var alice: Person? = Person(name: "Alice")  // Reference count: 1
var another = alice                          // Reference count: 2

alice = nil           // Reference count: 1 (another still holds it)
print("Set alice to nil")
another = nil         // Reference count: 0 → released
print("Set another to nil")

// Retain cycle example (memory leak)
class Apartment {
    let unit: String
    var tenant: Resident?  // Strong reference

    init(unit: String) {
        self.unit = unit
        print("Apartment \(unit) was created")
    }
    deinit { print("Apartment \(unit) was released") }
}

class Resident {
    let name: String
    var apartment: Apartment?  // Strong reference → retain cycle!

    init(name: String) {
        self.name = name
        print("\(name) was created")
    }
    deinit { print("\(name) was released") }
}

// Creating a retain cycle
var apt: Apartment? = Apartment(unit: "101")
var bob: Resident?  = Resident(name: "Bob")

apt!.tenant   = bob   // Apartment → Resident (strong reference)
bob!.apartment = apt  // Resident → Apartment (strong reference)

apt = nil   // Not released (Bob still holds a reference)
bob = nil   // Not released (apt still holds a reference)
print("--- Neither was released due to the retain cycle ---")

Notes

ARC does not apply to structs, enums, or primitive types. Only instances of classes (reference types) are managed by ARC.

When a retain cycle occurs, the reference count never reaches zero and deinit is never called. Retain cycles cause memory leaks. Use weak or unowned to break the cycle.

For details on resolving retain cycles with weak and unowned, see weak / unowned.

If you find any errors or copyright issues, please .