본문 바로가기
Swift Study

Strong Reference Cycle

by 창브로 2024. 2. 20.
728x90

이번 포스팅에서는 ARC의 Counting 방식으로 인해 생기는 Strong Reference Cycle에 대해 알아보겠습니다!

 

Strong Reference(강한 참조)란?

변수, 상수 등으로 클래스 인스턴스에 할당할 때를 의미합니다.

var strongRefernece = ChangbroClass()

 

해당 Refernece가 남아있는 한, 메모리에서 해제되지 않고 계속 메모리에 남아 있습니다. 이럴 때 Memory Leak이 발생합니다.

그럼 이제 Strong Reference Cycle이 일어나는 예제를 확인해 보겠습니다.

 

두 개의 클래스 객체가 서로 강한 참조를 하고 있고, 서로의 참조를 떼어놓지 못하고 있는 코드입니다.

class Job {
    var name: Name?
    
    deinit{
        print("Job 메모리 해제")
    }
}

class Name {
    var job: Job?
    
    deinit {
        print("Name 메모리 해제")
    }
}

var a: Job? = Job()
var b: Name? = Name()

a?.name = b
b?.job = a

 

 

a 변수는 Job의 객체를 갖고, b는 Name의 객체를 가지고 있습니다.

또한 a의 Job객체 내부에서는 b를 가지고 있습니다. b 또한 마찬가지로 객체 내부에서는 a가 가지고 있는 Job객체를 가지고 있습니다.

 

근데 이게 왜 Strong Reference Cycle이라는 거죠? nil로 초기화하면 되는 것 아닌가요?

이런 의문이 들 수 도있습니다.

아래 예시를 보시죠

 

 

원래라면 deinit이 실행되어서 print가 보여야 할 텐데 실행이 되지 않는 것을 볼 수 있습니다.

왜 이런 현상이 일어날까요?? 🤬

 

이전 포스팅에서 하나의 객체를 참조하는 변수들에 따라서 Reference Count가 올라간다고 설명드렸습니다.

a와 b에 nil을 할당하기 전 위 코드의 count를 확인해 보겠습니다.

 

그림에서 보시다시피 각각 a, b가 class를 참조할 때 count가 하나씩 올라가고 서로 내부에서 또 참조를 했을 때 하나씩 올라가 총 count는 2가 된 것을 확인할 수 있습니다!

 

nil을 할당한 직후 count를 그림으로 확인해 보겠습니다.

 

 

 

이러한 이유로 nil을 할당해도 count가 1이 되어 메모리에서 해제되지 못하고 있는 것이었습니다. 😶

앞에서 말씀드린 것처럼 이러한 경우는 Memory Leak의 주범이기 때문에 꼭 해결을 해야 합니다.

 

그럼 어떻게 해야 할까요?🤥

1. a와 b를 nil처리 하기 전 Job 인스턴스와 Name 인스턴스가 서로 참조하고 있는 구조를 해제시킵니다.

2. Job객체와 Name객체가 서로 참조할 때 Reference Count를 증가시키지 않도록 합니다.

 

하나 하나씩 알아보죠!!

 

1. Job 인스턴스와 Name 인스턴스의 서로 참조를 해제

 

a.name과 b.job도 nil을 할당해주며 count를 0으로 만들어 deinit이 실행되어 print문이 찍히는 것을 확인 할 수 있습니다!

 

2. Reference Count를 증가시키지 않는 법 (weak, unowned 사용)

 

 

Job 인스턴스와 Name 인스턴스의 서로를 참조 해제를 하지 않아도 메모리가 해제되며 print문이 찍히는 것을 확인할 수 있습니다!

weak이나 unowned를 사용하면 count를 증가시키지 않고 사용할 수 있습니다🤗

 

그럼 weak이랑 unowned는 뭐가 다른거죠???

다음 포스팅에서 알아보겠습니다!

수고하셨습니다👏

'Swift Study' 카테고리의 다른 글

Error Handling  (0) 2024.02.23
Optional  (0) 2024.02.21
weak, unowned  (0) 2024.02.20
ARC  (0) 2024.02.20
Class vs Struct  (0) 2024.02.19