ARC(Automatic Reference Counting)는 Swift에서 메모리 관리를 자동으로 해주는 시스템입니다. ARC는 객체가 언제 메모리에서 해제되어야 하는지를 자동으로 추적하고 관리하여, 개발자가 수동으로 메모리를 할당하거나 해제할 필요 없이 안정적으로 앱을 개발할 수 있게 해줍니다.
ARC의 작동 방식
- 참조 카운팅:
- Swift의 모든 클래스 인스턴스는 참조 카운트를 가지고 있습니다. 이 카운트는 해당 인스턴스를 참조하는 변수나 상수가 얼마나 많은지를 나타냅니다.
- 새로운 인스턴스가 생성되면 참조 카운트는 1이 됩니다.
- 인스턴스가 다른 변수나 상수에 할당될 때마다 참조 카운트가 증가합니다.
- 반대로, 변수가 더 이상 인스턴스를 참조하지 않을 때 참조 카운트는 감소합니다.
- 메모리 해제:
- 참조 카운트가 0이 되는 순간, ARC는 해당 인스턴스를 메모리에서 자동으로 해제합니다. 즉, 더 이상 사용되지 않는 메모리를 반환하여 앱의 메모리 사용을 최적화합니다.
class Person {
let name: String
init(name: String) {
self.name = name
print("\(name) is initialized")
}
deinit {
print("\(name) is being deinitialized")
}
}
var person1: Person? = Person(name: "John") // 참조 카운트 1
var person2 = person1 // 참조 카운트 2
person1 = nil // 참조 카운트 1
person2 = nil // 참조 카운트 0, 메모리 해제됨
위 코드에서 Person 객체는 person1과 person2가 참조하고 있을 때 참조 카운트가 2입니다. person1이 nil이 되면 참조 카운트는 1이 되고, person2도 nil로 설정되면 참조 카운트가 0이 되어 메모리에서 해제됩니다. 해제될 때 deinit 메서드가 호출되어 메모리 해제가 완료됨을 알립니다.
강한 참조 사이클 (Retain Cycle)
ARC가 참조 카운트 방식으로 메모리를 관리하다 보면 강한 참조 사이클 문제가 발생할 수 있습니다. 두 개 이상의 객체가 서로를 강하게 참조하고 있으면 참조 카운트가 0이 되지 않아 메모리에서 해제되지 않습니다. 이 문제를 방지하려면 약한 참조(weak) 또는 **비소유 참조(unowned)**를 사용해야 합니다.
class Person {
let name: String
var apartment: Apartment?
init(name: String) {
self.name = name
}
deinit {
print("\(name) is being deinitialized")
}
}
class Apartment {
let unit: String
var tenant: Person?
init(unit: String) {
self.unit = unit
}
deinit {
print("Apartment \(unit) is being deinitialized")
}
}
var john: Person? = Person(name: "John")
var unit4A: Apartment? = Apartment(unit: "4A")
john?.apartment = unit4A
unit4A?.tenant = john
// Apartment는 Person을, Person은 Apartment를 참조하는상황
john = nil // john이 nil이 되어도 참조 카운트는 0이 되지 않음
unit4A = nil // 강한 참조 사이클로 인해 메모리 해제되지 않음
이 문제는 weak 키워드를 사용하여 해결할 수 있습니다. 예를 들어, Apartment 클래스의 tenant 속성을 weak로 선언하면, Person 인스턴스가 강한 참조에서 벗어나 메모리에서 해제될 수 있습니다.
class Apartment {
weak var tenant: Person?
}
요약
- ARC(Automatic Reference Counting): Swift에서 클래스 인스턴스의 메모리를 자동으로 관리하는 시스템.
- 참조 카운트 증가/감소: 인스턴스가 참조될 때 카운트가 증가하고, 참조가 사라지면 감소.
- 메모리 해제: 참조 카운트가 0이 되면 인스턴스는 메모리에서 해제됨.
- 강한 참조 순환: 두 객체가 서로 강하게 참조할 때 발생하는 문제로, weak나 unowned 키워드를 사용해 해결 가능.
이렇게 ARC는 개발자가 직접 메모리 관리를 신경 쓰지 않아도 효율적으로 메모리를 관리해 주지만, 강한 참조 순환 문제는 주의해서 해결해야 합니다.