ARC(Automatic Reference Counting)

장수빈·2025년 6월 13일

CS

목록 보기
8/14

iOS는 Garbage Collection이 아닌 ARC를 사용하여 메모리를 관리
ARC는 컴파일 타임에 삽입된 코드로 객체의 참조 횟구(Reference Count)를 추적하고, 참조가 0이되면 메모리를 자동으로 해제

ARC의 동작 방식

  • 인스턴스를 다른 변수나 상수가 참조하면 -> 참조 횟수 + 1
  • 더 이상 참조되지 않으면 (모든 참조 해제) -> 참조 횟수 0 -> 자동으로 deinit 호출 및 메모리 해제
class Person {
    let name: String
    init(name: String) { self.name = name }
    deinit { print("\(name) is being deinitialized") }
}

var person1: Person? = Person(name: "Alice")
person1 = nil // 참조가 사라지므로 메모리 해제

ARC가 있어도 메모리를 관리해야 하는 이유

  • ARC는 모든 메모리 문제를 자동으로 해결하지 못함
  • 특히 순환 참조(Retain Cycle)가 발생하면, 참조 카운트가 0이 되지 않아 메모리 누수 발생
  • 또한 메모리 사용량 최적화, 타이밍 제어(deinit 시점) 등은 여전히 개발자 몫

참조 타입의 종류와 예시

참조 타입설명사용 시기 및 예시
strong기본 참조. 참조 카운트를 증가시킴대부분의 경우 기본 사용
weak참조는 하지만, 참조 카운트에 영향 X. 옵셔널이어야 함 (ClassType?)순환 참조 방지용 (특히 delegate) weak var delegate: SomeDelegate?
unowned참조는 하지만, 참조 카운트에 영향 X. nil이 되지 않음강한 참조 순환은 피하면서, 참조 대상이 deinit되기 전 반드시 살아있는 것이 보장될 때 unowned let owner: Person
class Customer {
    var card: CreditCard?
}

class CreditCard {
    unowned let customer: Customer
    init(customer: Customer) {
        self.customer = customer
    }
}

순환 참조?

두 객체가 서로를 강하게 참조(strong)하면, 참조 횟수가 0이 되지 않아 deinit이 호출되지 않음
-> 메모리 누수

ex)

class A {
    var b: B?
}
class B {
    var a: A?
}

var a: A? = A()
var b: B? = B()
a?.b = b
b?.a = a

a = nil
b = nil // 순환 참조로 인해 해제되지 않음

ex) 클로저에서의 순환 참조

class ViewModel {
    var name = "ViewModel"
    lazy var printName: () -> Void = {
        print(self.name) // self가 클로저를 소유, 클로저가 self를 참조 → 순환 참조
    }
}

해결 방법

lazy var printName: () -> Void = { [weak self] in
    print(self?.name ?? "nil")
}

ARC와 Garbage Collection의 차이

항목ARCGarbage Collection
방식참조 카운트 기반 (컴파일 시점)루트 객체 탐색 기반 (런타임 시점)
메모리 해제 시점참조가 0이 되는 즉시GC가 동작하는 타이밍에 일괄 처리
성능예측 가능 (낮은 지연시간)불규칙한 지연 가능성 있음 (Stop-the-world)
플랫폼 예시iOS (Swift, Objective-C)Java, C#, Android 등

ARC vs GC 장단점

ARC의 장점

  • 즉각적인 메모리 해제 -> 성능 예측 쉬움
  • 지연없는 UI -> iOS와 같이 반응성이 중요한 플랫폼에 적합
  • 런타임 비용 적음 (컴파일 시 결정)

ARC의 단점

  • 순환 참조는 방지는 개발자 책임
  • 일부 복잡한 메모리 구조에서 관리 어려움

GC의 장점

  • 순환 참조 자동 감지 및 해제
  • 메모리 관리가 자동화되어 개발자 부담 감소

GC의 단점

  • 예상치 못한 GC 수행 시간 -> UI 렌더링 지연
  • 런타임 비용 증가 (메모리 스캔)
profile
iOS 공부 이모저모 낙서장

0개의 댓글