[iOS] RxSwift(2) - Dispose가 뭘까

Madeline👩🏻‍💻·2024년 4월 6일

RxSwift study

목록 보기
2/6
post-thumbnail

https://velog.io/@maddie/iOS-RxSwift%EA%B0%80-%EB%AD%98%EA%B9%8C
위 포스트를 업데이트 했습니다.

앱마냥 자주 업데이트 할 것 같아, 버전도 써보았는데요,
다른 공부는 얼렁뚱땅 넘어갔어도 Rx만큼은 진짜 잘해보고 싶어서, 더 딮한 공부를 위해 새 포스트를 작성합니다.

RxSwift를 공부하다가, 쏟아지는 new 키워드와 이론의 향연에 정신을 못차리던 도중,
대충 Rx는 disposeBag이라는 가방🎒으로 끝을 내나보다~ 정도로 감을 잡고 있었는데,
어디선가 Disposable, dispose, disposeBag, ... 뭐지
나 영어영문학관데 이거 그냥 넘어가면 안되겠는데? 싶어서 정리를 제대로 해보겠습니다.

Dispose

실제로 Dispose는 버리다, 라는 의미로, disposable은 일회용이라는 의미로 흔히 사용된다.

Observable은 관찰 당하는 애, Observer는 관찰하는 애였고,
어떻게 관찰하냐? subscribe, 구독을 해서 이벤트를 관찰(데이터가 변하는지를 관찰)하는데,
그 이벤트를 더이상 관찰할 필요가 없다면?
흔히 유투브 구독 취소하는 것처럼, 이제 더 보지 않겠다고 하는 과정이 dispose다.

RxSwift에서는 Observable이 생성하는 이벤트 흐름(==스트림, 시퀀스)를 구독하고 나서, 구독 취소 하고, 관련된 리소스를 정리하는 과정을 말한다.

코드로 살펴보면,
우리가 Observable을 관찰하기 위해서 사용했던 subscribe 메서드의 반환형은 Disposable이다.

Disposable

Disposable은 뭐지? 코드로 또 들어가보면,

딸랑 dispose()라는 메서드를 가진 프로토콜이다.
dispose 과정을 관리하는 프로토콜인데, 이 프로토콜을 채택하는 객체를 통해 언제든지 구독을 취소할 수 있다.

그러니까, Observable을 관찰하기 위해서 썼던 subscribe 메서드는,
Disposable 타입의 인스턴스를 반환하는데,
그리고 Disposable 타입의 dispose()를 호출하면, 구독 취소가 되는 거다.

Memory Leak

RxSwift에서 구독이 어떻게 작동했었지?
subscribe를 하면, 그 이벤트(데이터 스트림)을 관찰하고 있어야 한다.
근데 만약에 계~속 구독하고 있으면, Observer는 계속 데이터 스트림이 올 때까지 기다리게 되고, 결국 메모리에서 해제되지 않는 메모리 누수가 생긴다.

Disposable의 효과는 여기에서 대단했다 !

dispose해줌으로써, 필요없어진 Observer와 데이터 스트림 사이의 구독 연결을 끊어, 메모리 누수를 방지하는 역할을 한다.

DisposeBag🎒

같은 맥락에서 DisposeBag은 여러 개의 Disposable을 관리해서,
객체가 더 이상 필요 없을 때, 한번에 모든 구독을 해제할 수 있도록 도와준다.

import RxSwift

class MyViewController: UIViewController {
    var disposeBag = DisposeBag()

    override func viewDidLoad() {
        super.viewDidLoad()

        let observable = Observable.of("Hello", "World")
        
        observable
            .subscribe(onNext: { value in
                print(value)
            })
            .disposed(by: disposeBag) // 구독 해제를 관리하기 위해 disposeBag에 추가
    }
}

Observable이 헬로 월드를 방출하는 동안, subscribe 메소드를 통해 이 스트림을 구독하고, 문자열이 방출될 때마다 print된다.
그리고 disposed(by: disposebag)을 호출함으로써, MyViewController의 인스턴스가 메모리에서 해제될 때, 모든 구독도 함께 해제되도록 관리한다.
이렇게 함으로써 메모리 누수를 방지할 수 있다.

disposeBag는 Disposable 객체를 담는 배열이다.

이렇게 Disposable 객체들을 줍줍해서 가방에 insert하면서 담아주고,
.disposed(by: disposeBag)
이 코드를 실행하면,
disposeBag 안에 해당 Disposable들이 모두 순회되면서 dispose() 된다.

레퍼런스

오늘도 스페셜 샤라웃 투 소들이님
https://babbab2.tistory.com/186

profile
🍎 Apple Developer Academy@POSTECH 2기, 🍀 SeSAC iOS 4기

0개의 댓글