Automatic Reference Counting

2019-06-11
Swift

안녕하세요. 도미닉입니다.

오늘은 스위프트의 특징 중에 하나인 Automatic Reference Counting(이하 ARC) 대해서 알아보겠습니다.

해석

reference 는 해석하면 참조입니다.

클래스 인스턴스를 변수, 상수, 프로퍼티 등에 저장하거나 메소드나 함수에 매개변수로 사용하면 참조를 한다라고 합니다.

Counting 은 해석하면 숫자를 세다라고 할 수 있죠.

Reference(참조)의 숫자를 세는 것이 Reference Counting 입니다.

그렇다면 ARC 는 어떻게 해석할 수 있을까요?

Automatic 은 자동이라는 뜻이죠.

Reference Counting 을 자동으로 해주는 것입니다.

ARC 의 동작

그렇다면 스위프트는 참조를 어떻게 카운팅할까요?

ARC 는 강한 참조만을 카운팅합니다.

강한 참조라는 용어가 익숙하지 않으실텐데요.

저희가 의식하지 않고 자주 사용하고 있었습니다.

변수나 상수에 클래스 인스턴스를 초기화해서 할당하는 것이 강한 참조입니다.

그렇다면 ARC 는 어떻게 동작할까요?

  • 위에서 예시를 드렸다시피 프로퍼티, 상수 또는 변수에 클래스 인스턴스를 할당하는 것을 강한 참조라고 합니다.

  • 인스턴스를 함수나 메서드에 인자로 전달하면 해당 블록이 실행되는 동안 참조 카운트가 증가하고 함수나 메서드가 종료되면 참조 카운트가 감소합니다.

  • 함수나 메서드, 클로저 등 코드 블럭 내에서 생성한 인스턴스는 당연히 해당 코드 블럭이 끝나면 참조 카운트가 감소합니다.

  • 강한 참조가 없다면 deinit 메서드가 실행된 후 해당 인스턴스는 자동으로 메모리에서 할당 해제됩니다.

  • 강한 참조가 남아있다면 해당 인스턴스를 할당 해제하지 못합니다.

강한 참조 순환 문제

이렇게 강한 참조로만 구성하면 문제가 없을까요?

강한 참조 순환 문제가 발생할 수 있습니다.

강한 참조 순환 문제는 두 개의 클래스가 서로를 프로퍼티로 강한 참조할 때

각 두개의 인스턴스가 메모리에서 할당되지 않고 계속 남아있는 문제입니다.

강한 참조 순환 문제 해결 방법

강한 참조 순환 문제를 해결하는 방법은 아래의 두가지가 있습니다.

  • 약한 참조

  • 미소유 참조

하나씩 자세히 설명해보도록 하겠습니다.

약한 참조

약한 참조는 프로퍼티나 변수 앞에 weak 을 붙여줘서 사용할 수 있습니다.

강한 참조가 순환되서 발생하던 문제는 한 쪽을 약한 참조로 바꿔주면 해결됩니다.

약한 참조를 사용할 때 사용할 때 주의할 점 두가지!

  • 약한 참조는 항상 변수로 선언해야 한다. 상수로 선언하면 안 된다.

  • 약한 참조는 항상 옵셔널로 선언해야 한다.

미소유 참조

미소유 참조는 프로퍼티나 변수, 상수 앞에 onowned 를 붙여줘서 사용할 수 있습니다.

강한 참조가 순환되서 발생하던 문제는 한 쪽을 미소유로 바꿔주면 해결됩니다.

미소유 참조를 사용할 때 사용할 때 주의할 점 두가지!

  • 참조하는 인스턴스가 메모리에서 해제되더라도 자동으로 nil 을 할당해주지 않음

  • 메모리에서 해제된 인스턴스에 접근하려 하면 잘못된 메모리 접근으로 런타임 오류가 발생해서 프로세스가 강제로 종료됨

정리

ARC 는 강한 참조를 자동으로 카운트한다!

강한 참조만 사용하면 클래스 인스턴스간 강한 참조 순환이 발생할 수 있다.

아래 두가지 방법으로 클래스 인스턴스간 강한 참조 순환은 해결할 수 있다.

  • 약한 참조

  • 미소유 참조

자세한 내용은 아래 발표 자료를 확인 부탁드립니다.

https://www.slideshare.net/joonjhokil/arc-149195450