👩💻 새롭게 공부하며 작성한 글이기 때문에 틀린 정보가 있을 수 있습니다! 이에 대한 피드백은 언제나 환영입니다 🙌
🔗 DisposeBag() 정복하기 1편을 안보고 오셨다면 보고오기!
그럼 지금부터 DisposeBag()에 대해서 알아보겠습니다!
정의를 살펴보면 DisposeBag은
deinit
할 때, 배열에 추가되어있는 disposable
들을 dispose
하는 것이다!ARC
의 RxSwift 버전이라고 할 수 있다.그럼 우리가 자주 사용하는 RxSwift의 DisposeBag을 이해해 보자.
먼저, DisposeBag을 사용하는 이유를 통해, DisposeBag의 기능을 생각해 보면,
이를 기억하고 있다면! 다음에 오는 내용을 쉽게 이해할 수 있을 것이다.
프로토콜 Disposable을 확장한 곳에는, disposed(by:)
라는 함수가 있다.
이것은 바로, 우리가 자주 보던 그것임.
let disposeBag = DisposeBag()
Observable.of(1, 2, 3)
.subscribe{
print($0)
}
.disposed(by: disposeBag)
이거이거.. 익숙하지요?
위의 Disposable의 함수를 보면, bag.insert(self)
라는 것이 들어잇음. 그럼 이건 뭐게?
DisposeBag에 들어있는 무언가 이겠지요.
insert(self)
라는 함수의 이름으로 보아서 bag에 추가해 주는 것이겠고, self는 Disposable이니까!
아마도 disposable들이 담겨져 있는 배열에 추가해 주는 것은 아닐까..? 하는 합리적 의심을 할 수 있음.
이제 아까 잠시 살펴본 DisposeBag으로 돌아와보자.
disposables
라는, 우리가 말한 Disposable들을 담을 배열을 가지고 있음.isDisposed
라는 지금은 알 수 없지만 해제되었는지 아닌지를 판단하는 것처럼 보이는 파라미터를 가지고 있음. 앞으로의 내용 이해를 돕기 위해 먼저 정답을 말하자면, 이게 맞다. 해제되었는지, 아닌지 판단하는 것!lock
그리고 조금 더 내려가면, DisposeBag이 가지고 있는 함수들을 만날 수 있는데
짜잔, 아까 본 insert
를 바로 만났다.
먼저 self.lock.performLocked
는 우선 값의 변경이 끝나기 전에 외부에서 접근하지 못하게 막는 것이라고 생각하고 넘어가자.
그리고 아래를 살펴보면, isDisposed
가 true
이면, disposable
을 리턴하고,
아니면 disposables
에 추가함.
앗! 글쿤. (?
자,
앞의 내용을 이해하면서 따라왔다면, 쉽다!
public func insert(_ disposable: Disposable) {
self._insert(disposable)?.dispose()
}
insert(_:)
함수에서
_insert(disposable)?
의 결과가 있으면(nil이 아니면) dispose()
를 시켜서 메모리를 정리한다.
근데 dispose()
가 대체 먼데.. 너 그거 머냐..그래서..먼데..
insert(_:) 함수로부터 반환된 Disposable
타입 프로토콜의 요구사항인 func dispose()
에 접근하는 것인데,
이놈이 어디에 구현되어 있는지 모르겠다...
👉 우선은, dispose()
라는 것이 모든 옵저버와 리소스들의 구독을 취소하는 역할을 한다는 점을 알고, 넘어가도록 하자.
그 다음에 알아볼 것은 disposeBag이 deinit
되는 시점에 호출되는 dispose()
입니다!
이는 disposeBag이 메모리에서 내려갈 때에 자동으로 호출되어 더이상 사용하지 않는 리소스들을 정리하고 메모리 누수를 막을 수 있도록 기능을 하는 것입니다.
자세히 살펴 볼까요?
let oldDisposables = self._dispose()
아.. 이건 또 머지요? 살펴봅시다.
먼저 위의 파라미터를 이해하기 위해서 _dispose()
를 보면, 일단 [Disposable]을 리턴하는 것.
self.lock.performLocked
이거 살포시 패스하고...(쓰레드에 접근 못하게 막아주고)
disposables
를 새로운 변수에 저장해두고,isDisposed
를 true
로 만들어줌.disposables
를 리턴함. (방금 비운거 말고, 기존의 disposables를 리턴)그리고 dispose()
함수로 돌아가서,
oldDisposables
, 즉 원래의 disposables의 내부에 있는 disposable
들을 순회하면서,dispose()
를 통해 메모리에서 내려준다!이해 가셨나요?
결국은 disposeBag()
클래스 인스턴스에 있는, 지워져야햐는 대상 목록이 비워지고, 실제로 메모리에서도 해제
되는 것입니다!
이제 DisposeBag에 대해서 이해가 가셨기를!
그럼 2000...(우와진짜 옛날사람