[Swift] ARC, strong, weak, unowned

MinTa·2022년 1월 24일
0
post-thumbnail

...

Instance는 하나 이상의 소유자가 있는 경우에만 유지되고, 0이 되는 순간 메모리에서 ARC에 의해 해제된다.
제거시점을 파악하기 위해 소유자 수를 저장하는데 이것을 Reference Count(RC)라 한다.

그렇다면 ARC가 뭔가?

ARC (Automatic Reference Counting)

정확히는 Swift언어에서 제공해주는 것은 아니고 애플이 제공하는 개발환경인 Cocoa에서 제공해주는 것.
소유자 수(참조된 횟수)를 추적해 더 이상 참조하지 않는 instance를 메모리에서 해제해주는 것.
자동으로 RC를 관리해줌으로써 메모리 해제에 대한 개발자들의 부담을 덜어줌.

ARC가 사용하는 3가지 참조

1. Strong Reference
strong은 기본적인 Reference Counting 방식으로 instance와 소유자는 이어짐.
instance를 소유(retain)할때마다 Reference Count(RC)가 1씩 증가하고 release할 때마다 1씩 감소한다.

기본적으로 strong 포인터는 힙안에 있는 것들을 힙에 머물도록 강제하는 것.

2. Weak Reference
강의의 말을 빌리자면

If no one else is interested in this heap, then neither am I, set me to nil in that case

힙에 있는 것에 아무도 관심이 없다면 힙에서 제거할 수 있고 nil로 설정한다는 말이다.

힙에 있는 어떤 것을 가르키고는 있긴 하지만, 그 안에 뭐가 들었는지는 그닥 관심없으니 사라져버리면 그냥 nil로 할꺼야~ 라고 말하는 것과 같다.
또한, nil로 설정한다는 것은 Optional 포인터여야 한다는 뜻이다.
결국 weak은 오직 옵셔널 타입의 포인터에만 적용이 된다.

weak의 좋은 예로 @IBOutlet weak var textLabel: UILabel!이 있다.
UILabel의 superview는 UILabel에 대해 strong 포인터를 갖고 있고, 그래서 outlet을 힙 안에 넣어둘 필요가 없음. -> 뷰 계층에 따라 알아서 힙에 보관될테니까? -> 하지만 뷰게층이 그 UILabel을 제거해버린다면, 즉 더이상 뷰의 일부분이 아니게 된다면 그냥 nil로 설정하게 된다.

3. Unowned Reference
Unowned는 옵셔널이 아니기 때문에 이 포인터가 가르키는 곳에 아무것도 없다면 앱은 충돌을 일으키게 되니 매우 신중히 써야한다.

Strong Reference Cycle (강한 참조 사이클)

ARC가 RC를 참조해 메모리 해제에 개발자들의 부담을 덜어주지만, 강한 참조 싸이클까지 고려해주지는 않는다. 강한 참조 싸이클, 순환참조라고도 불리는 이것은 서로가 서로를 참조하고 있어 메모리 해제가 정상적으로 이루어지지 않는 것을 말한다.

해결방법

Weak ReferenceUnowned Reference로 해결할 수 있다.
Weak와 Unowned는 약한 참조로써 Strong Reference와 달리 RC를 증가시키지 않는다.
Weak는 Optional형식으로 nil이 올 수 있으며 메모리가 해제되는 순간에 자동으로 nil로 초기화된다.
Unowned는 non-optional형식으로 nil이 올 수 없으며 메모리가 해제되는 순간에 dangle-pointer만 남게 된다.

  • dangle-pointer : 원래 바라보던 객체가 메모리 해제되면서 할당되지 않는 빈공간을 가리키는 포인터

참고 블로그 : https://shark-sea.kr/entry/iOS-ARC-strong-weak-unowned
참고 강의 : iOS를 위한 swift5 완벽 가이드(인프런 강의)

profile
지(치지않고)꾸(준히)열(심히)

0개의 댓글