Middle
What is automatic link counting?
sobes.tech AI
Answer from AI
Automatic Reference Counting (ARC) is a memory management mechanism in Swift and Objective-C that automatically tracks and releases memory allocated for objects. Each class instance has a reference count that increases when a strong reference to the object is created and decreases when it is removed. When the reference count reaches zero, ARC automatically deallocates the object and frees the memory it occupied.
ARC prevents memory leaks and double freeing, simplifying memory management compared to manual management (as in Objective-C without ARC).
There are three types of references:
- Strong: Increases the reference count of the object. It is the default reference type.
- Weak: Does not increase the reference count. Used to prevent strong reference cycles when two objects strongly reference each other. A weak reference becomes
nilif the object it points to is deallocated. Defined with theweakkeyword. - Unowned: Does not increase the reference count and always has a value. Used when it is known that the reference will always point to an object as long as the object exists. Unlike
weak, an unowned reference does not becomeniland can cause a crash if accessed after the object is deallocated. Defined with theunownedkeyword.
Example of a strong reference cycle:
class Human {
let name: String
var apartment: Apartment? // Strong reference to optional Apartment
init(name: String) {
self.name = name
print("\(name) is being initialized")
}
deinit {
print("\(name) is being deinitialized")
}
}
class Apartment {
let unit: String
var tenant: Human? // Strong reference to optional Human
init(unit: String) {
self.unit = unit
print("Apartment \(unit) is being initialized")
}
deinit {
print("Apartment \(unit) is being deinitialized")
}
}
var john: Human?
var unit4A: Apartment?
john = Human(name: "John Appleseed")
unit4A = Apartment(unit: "4A")
john!.apartment = unit4A
unit4A!.tenant = john
john = nil
unit4A = nil
// Neither "John Appleseed is being deinitialized" nor "Apartment 4A is being deinitialized" will be printed due to the strong reference cycle
Solution to the strong reference cycle using weak:
class Human {
let name: String
var apartment: Apartment?
init(name: String) {
self.name = name
print("\(name) is being initialized")
}
deinit {
print("\(name) is being deinitialized")
}
}
class Apartment {
let unit: String
weak var tenant: Human? // Weak reference
init(unit: String) {
self.unit = unit
print("Apartment \(unit) is being initialized")
}
deinit {
print("Apartment \(unit) is being deinitialized")
}
}
var john: Human?
var unit4A: Apartment?
john = Human(name: "John Appleseed")
unit4A = Apartment(unit: "4A")
john!.apartment = unit4A
unit4A!.tenant = john
john = nil // John is deallocated as its reference count becomes 0
unit4A = nil // Apartment is deallocated as its reference count becomes 0