ARC 란
Swift 에서 사용하는 메모리 관리 전략이다.
reference 숫자를 자동으로 counting 하여 메모리를 관리한다.
객체가 메모리에 할당될 때 reference를 저장하는 객체만 ARC의 영향을 받는다.
그말은 reference type 만 ARC 의 관리를 받는 다는 뜻으로 구조체와 같은 value type은 메모리 관리 대상이 아니다
Reference type으로는 대표적으로 Class 와 Closure이 있다.
자바의 메모리 관리 기술인 Garbage Collector 과 비교하자면 ARC는 컴파일 시간에 동작하고 GC는 런타임에 동작한다는 것이다.
ARC가 compile 타임에 동작하기 때문에
개발자는 ARC에게 메모리 leak 에 대비할 수 있도록 많은 힌트를 줘야 한다.
reference의 종류에는 3가지가 있다.
- Strong
- weak
- unowned
Strong Reference 는 ARC의 default 값으로 따로 명시하지 않으면 strong 으로 참조된다. 해당 레퍼런스에 대한 강한 참조를 유지시키고 reference count를 증가시킨다.
하지만 Strong Reference 만 사용하면 Strong Reference Cycle (강한순환참조)가 일어날 수 있다.
Class Person 과 Class Apartment 가 있고 서로 프로퍼티에 상대방의 Class 인스턴스를 가지는 Optional 한 변수가 있다고 생각 할때
인스턴스화 된 Person 인 john 과 Aparment 인 unit4A에 서로 각각의 인스턴스를 할당해 주면 위 그림과 같은 상황이 된다.
저 상태로 var john = nil 과 var unit4A = nil 을 하게되면 수직으로 연결된 strong reference count 는 감소되지만 Person instance 와 Apart instance 끼리 수평으로 연결된 strong reference 에 접근할 수 있는 방법이 없어진다. 즉 메모리 누수가 발생한다.
이 현상을 해결하기 위해 weak와 unowned가 있다.
weak 의 경우 해당 객체가 nil이 될 수 있음을 뜻한다. 항상 optional 로 선언되어야 하며 weak를 통해 생긴 인스턴스의 경우 reference count를 세지 않고 추후에 strong reference 가 해제되면 자동으로 weark reference 가 메모리에서 해제된다.
unowned 의 경우는 weak 와 비슷하지만 optional 이 아니라는 차이점이 있다. unowned 값이 무조건 있다는 가정하에 사용하기 때문에 nil이 되지 않는 확실한 상황일때 사용해야 한다.
Lazy 를 통해 객체가 초기화 된 후 사용하기 직전에 프로퍼티 값을 초기화 할 때 클로저가 변수에 대해 값을 획득하기 때문에 순환참조가 발생할 수 있다. 이때 self 를 통해 접근하는 경우 self는 값이 있음을 가정하므로 unowned self 를 통해 self 에 접근할 수 있다.
[출처]http://minsone.github.io/mac/ios/rules-of-weak-and-unowned-in-swift
내 생각엔 RxSwift 를 쓸때 unowned self 를 많이 봤는데 위 lazy 와 비슷한 맥락인 것 같다.
//가입하기 버튼
signInButton.rx.tap.do(onNext: {[unowned self] in
self.emailTextField.resignFirstResponder()
self.emailTextField.resignFirstResponder()
}).subscribe(onNext: {[unowned self] in
let SignInStoryboard = UIStoryboard(name: "SignIn", bundle: nil)
let SignInVC = SignInStoryboard.instantiateViewController(identifier: "SignInVC")
SignInVC.modalPresentationStyle = .popover
self.present(SignInVC, animated: true, completion: nil)
}).disposed(by: disposeBag)
참고
'Swift' 카테고리의 다른 글
Swift High Order Function Summary (0) | 2020.10.06 |
---|---|
[DI] Initializer로 Swift 의존성 주입하기 (0) | 2020.09.03 |
Swift: 프로퍼티와 메서드 (0) | 2020.07.13 |
Swift: 구조체 vs 클래스 (0) | 2020.07.13 |
Swift enum - 열거형 (0) | 2020.07.09 |
댓글