아요 개발 일기

[Swift] ARC(Automatic Reference Counting) 본문

Swift

[Swift] ARC(Automatic Reference Counting)

소진이 2023. 1. 29. 15:12

안녕하세요!

스위프트 공부하다보니, 메모리 구조에 대해 찾아보게 되었는데요!

메모리 구조에 대해서 잘 모르시는 분들은   [Swift] 메모리 구조 포스팅을 참고해주세요 :D


 

자..

ARC를 제대로 알아보기 전에..

Apple이 Swift가 나오기 전에 사용했던 언어!

Object - C에서의 메모리 관리를 간단히 알아보겠습니다ㅎㅎ

 

출처 : https://i1.ruliweb.com/ori/21/02/01/1775da0b8275221e6.gif

 

Object - C에서는 retain, release, autorelease 등을 통해

수동으로 메모리 관리를 했었습니다.

이를 MRC(Manual Reference Counting)라고 칭해요!

 

 

간단히 retain과 release에대해서 설명해보자면 아래와 같습니다

 


retain: retain count(= reference count) 증가를 통해

현재 Scope에서 객체가 유지되는 것을 보장

 

release: retain count(= reference count)를 감소시킴.

retain후에 필요 없을 때 release 함


 

코드짤때 매우 복잡했을 것 같네요..

 

 

그러다 드디어!

WWDC2011에 ARC가 등장합니다.

그 후부터 Swift는 무조건 ARC를 통해 메모리 관리를 하게됩니다 :D

 

이제 본격적으로 ARC에대해 알아볼까요?ㅎㅎ

 


 

ARC (AutomaticReference Counting) ??

 

공부를 하다보면

스위프트는 메모리 관리를

ARC 방식으로 한다고 한번쯤 들어보셨죠?

 

 

ARC??

그게 뭔데ㅔ?? 😣

 

 

Automatic Reference Counting를 직독직해를 하면

"자동으로 참조를 세주는 것"이라고 해석됩니다!

 

 

메모리 관리를 해준다고 했는데...

참조를 세는거랑 무슨 상관이지?

 

 

자, 잘 모르겠으니

Apple 공식 문서에는 어떻게 설명을 하고있는지 보러 가봅시다!

 

 

맨위 상단에서 정의하는 부분만 가져와 봤어요!!

표시되어있는 부분을 해석해보면 

 

 

"ARC는 해당 인스턴스가 더 이상 필요하지 않을 때

클래스 인스턴스에서 사용하는 메모리를 자동으로 해제합니다."

 

 

라는 내용이 있습니다

아~ 이제 아까 직독직해한 해석이

이해가 조금 되네요!!

 

 

ARC가 자동으로 참조를 세어주고 

더이상 참조가 없을때 메모리를 힙영역에서

 자동으로 해제해주는 구나 :ㅇ

 

 

그럼, 이제 ARC는 메모리 관리를

어떻게 하는지 알아봅시다!

 


 

ARC의 메모리 관리

 

힙 영역의 메모리를 관리하는 방법에는 GC RC가 있습니다

 

 

GC(Garbage Collection) Runtime에 동적으로 감시하고 있다가,

더 이상 사용할 필요가 없다고 여겨지는 것을 해제시켜 버립니다.

 

RC(Reference Count) Compile time에메모리의 참조 횟수(RC)를 계산하여,

참조 횟수가 0이 되면 더 이상 사용하지 않는 메모리라 생각하여 해제합니다.

 

 

여기서 ARC는

Reference Count (참조 횟수)

를 이용한다고 했죠?

Object-C에서는 직접 retain과 release 선언을해서 

메모리 참조 횟수를 증감시켰는데..

 

Swift의 ARC는

어떻게 메모리 참조 횟수를 자동으로 증감시키는 걸까요?!

 

 

 

짠! 위의 이미지처럼

 

Compile time에 자동으로

retain, release를 적절한 위치에 삽입하여 retainCount를 관리하고,

0이 될때 deinit을 호출해서 메모리 해제를 시킵니다.

 

이론으로는 이해가 갔는데..

예제 코드를 통해 ARC가 실제 어떻게 동작하는지 확인해봅시다!

 


 

ARC in Action

 

ARC 동작하는지 알아보기로 했었죠?

먼저 하나의 클래스를 선언하고,

클래스의 인스턴스가 생성되거나 해지될때

print로 로그를 찍게 구현한 클래스를 만들어줍니다 :D

 

 

그럼 이제 변수를 선언해야겠죠?

Person 클래스 타입을 가지고 있는 reference 변수 3개를 선언해줍니다

모두 옵셔널 타입이라 초기값 nil을 갖고 있겠져?

 

 

준비 다 했으니!

참조횟수를 추가해봅시당

 

Reference Count Up (+)

 

 

Person 인스턴스를 생성하고 

reference1 변수가 참조하도록해줍니당

 

참조가 되었으니,

아까 설정해주었던 print문이 출력이되겠죠??

 

 

스택, 힙 영역을 이해하기 쉽게 그림으로 같이 그려보았어요!!

지금 요로케 참조하고있습니당

 

 

나머지 두 reference 변수들도

reference1 변수를 참조하도록 설정해줍니다@@

 

reference1변수가 Person 인스턴스를 참조하고있으니,

나머지 reference 변수도 Person 인스턴스를 참조하고있겠죠???

 

 

스택과 힙 영역은 위와 같은 상태가 됩니다!

 

참조 횟수를 추가해보았으니,

이번에는 참조 횟수를 줄여보겠습니당

고고!!

 

Reference Count Down (-)

 

참조 횟수를 줄이는 방법은

간단하게 할당(참조)을 해지해주면됩니다.

즉, nil 값을 주면 됩니다!!!!

 

 

위의 코드를보면 reference1, reference2에

nil 값을 주었죠??

 

 

위 이미지와 같이 참조가 해지되고,

reference3만 Person 인스턴스를 참조하고 있습니다.

 


여기서!!

reference3은 reference1을 참조하고있었는데..

왜 reference1이 참조 해지 되었어도 reference3는 그대로 Person을 참조하고있을까요??

 

그 이유는 reference 3가

reference1이 참조하는 Person 클래스의 주소값을 참조했기때문이에요!!

 

그래서 reference 1이 nil 값을 가져도 Person 인스턴스의 주소 값을 그대로 가지고 있는겁니당 


 

이번에는 reference3의 값도 참조 해지하여

참조 횟수를 0으로 만들어보겠습니다!

 

 

ARC가 Person 인스턴스를 메모리에서 해지하고,

Person 내부에 참조가 없으면 출력하기로한 문장도 출력되네여!

 


 

자!

ARC에대해 이해하셨나요?

그간 ARC를 애매하게 알고 있었는데,

정리하면서 많이 알 수 있었던 시간이었어요! :D

 

다음 시간에는 이번 글에서 못 다룬

weak, strong reference에 대해 알아보겠습니다!!

혹시 잘 못 적어 놓은 정보가 있다면 

댓글 아주아주 환영합니다 :D 

감사합니당