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

Since: Swift 1.0(2014)

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

sample_arc_strong_reference.swift
class Person {
    let name: String

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

    // 'deinit' is a method called just before the instance is freed from memory.
    deinit {
        print("\(name) released")
    }
}

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

ref1 = nil // Reference count: 1 (another still holds it)
print("Set ref1 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("Room \(unit) created")
    }
    deinit { print("Room \(unit) released") }
}

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

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

// Creating a retain cycle
var apt: Apartment? = Apartment(unit: "101A")
var res1: Resident? = Resident(name: "user_y")

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

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

Running the above produces the following output:

swift arc_strong_reference.swift
user_x created
Set ref1 to nil
user_x released
Set another to nil
Room 101A created
user_y created
--- 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 .