Sobes.tech
Junior

What is ARC (Automatic Reference Counting) in iOS?

sobes.tech AI

Answer from AI

ARC is a memory management mechanism in iOS that automatically counts references to objects. When the reference count to an object reaches zero, ARC automatically frees the memory occupied by that object.

Advantages of ARC:

  • Reducing memory leaks: Automating the memory release process reduces the likelihood of errors related to forgotten release or dealloc.
  • Reducing crashes due to double freeing: ARC prevents attempts to free memory that has already been freed.
  • Simplifying code: Developers do not need to manually manage memory, making the code cleaner and more understandable.

Despite automation, when using ARC, it is important to understand the concepts of strong and weak references to avoid strong reference cycles (retain cycles).

Example of a strong reference:

class Person {
    var name: String
    var apartment: Apartment?

    init(name: String) {
        self.name = name
        print("\(name) is being initialized")
    }

    deinit {
        print("\(name) is being deinitialized")
    }
}

class Apartment {
    var unit: String
    var tenant: Person? // Strong reference

    init(unit: String) {
        self.unit = unit
        print("Apartment \(unit) is being initialized")
    }

    deinit {
        print("Apartment \(unit) is being deinitialized")
    }
}

var john: Person?
var unit4A: Apartment?

john = Person(name: "John Appleseed")
unit4A = Apartment(unit: "4A")

// Creating strong references on both sides
john!.apartment = unit4A
unit4A!.tenant = john

// Nullifying references does not lead to deinit due to cycle
john = nil
unit4A = nil

Example of using weak reference to break the cycle:

class Person {
    var name: String
    var apartment: Apartment?

    init(name: String) {
        self.name = name
        print("\(name) is being initialized")
    }

    deinit {
        print("\(name) is being deinitialized")
    }
}

class Apartment {
    var unit: String
    weak var tenant: Person? // Weak reference

    init(unit: String) {
        self.unit = unit
        print("Apartment \(unit) is being initialized")
    }

    deinit {
        print("Apartment \(unit) is being deinitialized")
    }
}

var john: Person?
var unit4A: Apartment?

john = Person(name: "John Appleseed")
unit4A = Apartment(unit: "4A")

john!.apartment = unit4A
unit4A!.tenant = john

// Nullifying references leads to deinit (cycle is broken)
john = nil // Person deinitialized
unit4A = nil // Apartment deinitialized

ARC applies to class objects. Structures and enumerations are value types and are not subject to automatic memory management via ARC.