ARC

JG Ahn·2024년 11월 5일

swift 심화

목록 보기
3/18
post-thumbnail

ARC (Automatic Reference Counting)

  • Reference Type의 인스턴스 메모리를 자동으로 관리
  • 인스턴스가 필요하지 않으면 메모리에서 자동으로 해제
  • Reference Type 타입을 참조할 때 참조카운트가 증가하는 것을Strong 참조라고 함

ARC 동작 방식

1️⃣ 인스턴스 생성 / 메모리 할당

  • class의 인스턴스가 생성될 때 ARC가 인스턴스 정보를 메모리에 할당
    (인스턴스 정보 : 타입 정보, 프로터피 값)

2️⃣ 참조카운트 관리

  • ARC는 사용중인 인스턴스가 메모리에서 해제되지 않도록 추적
    (몇개의 변수, 상수, 프로퍼티가 인스턴스를 참조하는지)
    • 참조 시작 : 카운트 + 1
    • 참조 종료 : 카운트 - 1
    • 카운트 0이 되면 메모리 해제

3️⃣ 메모리 해제

  • 참조카운트 0인 인스턴스는 메모리 해제
    (만약 참조카운트가 0이 되기 전에 해제되면, 그 인스턴스 접근시 충돌 발생)

ARC 동작 시기

  • 컴파일 시 ARC가 자동으로 인스턴스 참조 카운트 코드 삽입

메모리 누수

  • 사용이 끝난 인스턴스가 메모리에 남아있는 상태 ➡️ 성능 저하
  • 주 원인 : 강한순환참조(Strong Reference Cycle)
    • 2개의 인스턴스가 각각 인스턴스를 생성하고 Strong으로 참조하면 발생
      (Strong 참조가 기본 값)
  • 해결방법 : 참조카운트를 올리지 않음으로써 방지
    • weak, unowned 사용 (strong 대신)
//Person과 Apartment가 서로 인스턴스를 참조하는 상황
class Person {
    let name: String
    init(name: String) { self.name = name }
    weak var apartment: Apartment? //weak로 참조카운트 방지
    deinit { print("\(name) is being deinitialized") }
}

class Apartment {
    let unit: String
    init(unit: String) { self.unit = unit }
    weak var tenant: Person? //weak로 참조카운트 방지
    deinit { print("Apartment \(unit) is being deinitialized") }
}

객체 참조 방법

1️⃣ strong - 강한 참조

  • 참조의 Default
  • 객체 참조시 참조카운트 + 1
  • 객체 참조시 참조카운트 - 1

2️⃣ weak - 약한 참조

  • 객체를 참조/종료시 참조카운트 변하지 않음
  • nil 허용

3️⃣ unowned - 미소유 참조

  • 객체를 참조/종료시 참조카운트 변하지 않음
  • nil이면 출동

0개의 댓글