안녕하세요. 도미닉입니다.
오늘은 스위프트의 특징 중에 하나인 Automatic Reference Counting(이하 ARC) 대해서 알아보겠습니다.
해석
reference 는 해석하면 참조입니다.
클래스 인스턴스를 변수, 상수, 프로퍼티 등에 저장하거나 메소드나 함수에 매개변수로 사용하면 참조를 한다라고 합니다.
Counting 은 해석하면 숫자를 세다라고 할 수 있죠.
Reference(참조)의 숫자를 세는 것이 Reference Counting 입니다.
그렇다면 ARC 는 어떻게 해석할 수 있을까요?
Automatic 은 자동이라는 뜻이죠.
Reference Counting 을 자동으로 해주는 것입니다.
ARC 의 동작
그렇다면 스위프트는 참조를 어떻게 카운팅할까요?
ARC 는 강한 참조만을 카운팅합니다.
강한 참조라는 용어가 익숙하지 않으실텐데요.
저희가 의식하지 않고 자주 사용하고 있었습니다.
변수나 상수에 클래스 인스턴스를 초기화해서 할당하는 것이 강한 참조입니다.
그렇다면 ARC 는 어떻게 동작할까요?
위에서 예시를 드렸다시피 프로퍼티, 상수 또는 변수에 클래스 인스턴스를 할당하는 것을 강한 참조라고 합니다.
인스턴스를 함수나 메서드에 인자로 전달하면 해당 블록이 실행되는 동안 참조 카운트가 증가하고 함수나 메서드가 종료되면 참조 카운트가 감소합니다.
함수나 메서드, 클로저 등 코드 블럭 내에서 생성한 인스턴스는 당연히 해당 코드 블럭이 끝나면 참조 카운트가 감소합니다.
강한 참조가 없다면 deinit 메서드가 실행된 후 해당 인스턴스는 자동으로 메모리에서 할당 해제됩니다.
강한 참조가 남아있다면 해당 인스턴스를 할당 해제하지 못합니다.
강한 참조 순환 문제
이렇게 강한 참조로만 구성하면 문제가 없을까요?
강한 참조 순환 문제가 발생할 수 있습니다.
강한 참조 순환 문제는 두 개의 클래스가 서로를 프로퍼티로 강한 참조할 때
각 두개의 인스턴스가 메모리에서 할당되지 않고 계속 남아있는 문제입니다.
강한 참조 순환 문제 해결 방법
강한 참조 순환 문제를 해결하는 방법은 아래의 두가지가 있습니다.
약한 참조
미소유 참조
하나씩 자세히 설명해보도록 하겠습니다.
약한 참조
약한 참조는 프로퍼티나 변수 앞에 weak 을 붙여줘서 사용할 수 있습니다.
강한 참조가 순환되서 발생하던 문제는 한 쪽을 약한 참조로 바꿔주면 해결됩니다.
약한 참조를 사용할 때 사용할 때 주의할 점 두가지!
약한 참조는 항상 변수로 선언해야 한다. 상수로 선언하면 안 된다.
약한 참조는 항상 옵셔널로 선언해야 한다.
미소유 참조
미소유 참조는 프로퍼티나 변수, 상수 앞에 onowned 를 붙여줘서 사용할 수 있습니다.
강한 참조가 순환되서 발생하던 문제는 한 쪽을 미소유로 바꿔주면 해결됩니다.
미소유 참조를 사용할 때 사용할 때 주의할 점 두가지!
참조하는 인스턴스가 메모리에서 해제되더라도 자동으로 nil 을 할당해주지 않음
메모리에서 해제된 인스턴스에 접근하려 하면 잘못된 메모리 접근으로 런타임 오류가 발생해서 프로세스가 강제로 종료됨
정리
ARC 는 강한 참조를 자동으로 카운트한다!
강한 참조만 사용하면 클래스 인스턴스간 강한 참조 순환이 발생할 수 있다.
아래 두가지 방법으로 클래스 인스턴스간 강한 참조 순환은 해결할 수 있다.
약한 참조
미소유 참조
자세한 내용은 아래 발표 자료를 확인 부탁드립니다.