본문 바로가기

iOS

[iOS] Auto Referencing Counting

Auto Referencing Counting

Auto Referencing Counting(이하 ARC)는 자동으로 메모리를 관리하는 메커니즘이다. 객체에 대한 참조 수를 관리하고 특정 객체의 참조 수가 0이 되었을 때 해당 객체를 메모리에서 해제한다. JVM 진영에서는 Garbage Collector(이하 GC)와 유사하지만 다른 점이 많다. ARC는 컴파일 타임에 결정되지만, GC는 런타임에 수행된다.

Objective-C에서는 메모리 관리를 수동으로 수행했지만, 최근 버전에는 ARC를 지원하며, Swift는 ARC를 자동으로 지원한다.

ARC가 동작하는 원리

위에서 언급한 것 처럼 Objecitve-C는 메모리 관리를 수동으로 했다. 이 때, 참조 수를 증가시키기 위해 retain, 감소시키기 위해 release 키워드를 사용했다. ARC는 이를 컴파일 타임에 자동으로 적절한 위치에 삽입시켜준다. 이 과정에서 개발자는 작성해야 될 코드 수가 줄어들고, 메모리 관리에 대한 걱정이 줄어든다.

좀 더 디테일한 객체의 메모리 관리는 다음과 같다.

  1. 동적 할당으로 객체가 생성되면, Heap Object에서 관리된다.
  2. Heap Object는 객체와 Reference Count를 관리한다.

이 과정에서 autorelease pool이라는 개념도 존재한다. autorelease pool은 ARC에 의해 autorelease된 객체가 등록되는 공간이다. pool이 해제될 때 실제로 객체가 메모리에서 소멸된다.

Strong Reference Cycles

위의 ARC에 의해 개발자가 메모리 관리에 대해 전혀 신경을 쓰지 않아도 되는 것은 아니다. 그 대표적인 예가 Strong Reference Cycle이다. 이는 메모리에 존재하는 두 객체가 서로를 참조하고 있을 때 발생한다.

class Person {
    let name: String
    var apartment: Apartment?
    init(name: String) {...}
    deinit {print("\(name) is deinitialized)}
}

class Apartment {
    let unit: String
    var tenant: Person?
    init(unit: String) {...}
    deinit {print("\(unit) is deinitialized)}
}

Apartment와 Person 클래스가 존재하는 상황이다. 만약, 두 객체가 초기화된 뒤 다음과 같은 코드가 있다고 생각해보자.

let john = Person("John")
let unit4 = Apartment("Unit4")

john.apartment = unit4
unit4.tenant = john

이 과정에서 서로에 대한 강한(strong) 참조가 생긴다. 단방향적인 참조는 문제가 없지만, 양방향적인 참조가 생긴다.

이 때, 아래를 수행하면 메모리에서 해제되지 않는 것을 확인할 수 있다.

john = nil
unit4A = nil

이를 해결하기 위해 weak 키워드를 사용할 수 있다. 이 때, 더 수명이 짧은 인스턴스에 weak(약한 참조)를 사용해야된다. 먼저, 할당이 해제될 수 있기 때문이다. 그렇기 때문에 바뀐 코드는 다음과 같다.

class Apartment {
    let unit: String
    weak var tenant: Person?
    init(unit: String) {...}
    deinit {print("\(unit) is deinitialized)}
}

이제 아래를 수행하면, John이라는 Person 객체도 사라지고, Apartment는 약한 참조를 갖고 있었기 때문에 tenant가 nil로 설정된다.

john = nil

이 과정에서 유의할 점은 weak는 언젠가 nil로 변환된 가능성를 내포하고 있기 때문에 var 타입과 Optional로 설정되어야한다.

'iOS' 카테고리의 다른 글

[iOS] Dispatch Queue  (0) 2023.01.07
[iOS] Weak, Strong Reference  (0) 2022.05.15