RxSwift 시작하기(subscribe, dispose) - 3

DevelopRecord·2022년 7월 17일
0

RxSwift

목록 보기
3/7
post-thumbnail

두번째 글에서 subscribe, dispose에 대해 간단하게 보였습니다.
항상 Rx에 대해 이해가 확 와닿지 않았는데 마기님 블로그 보면서 다시 내가 직접 써보니까 차츰 이해가 되고 있어요.

우선 Observable의 역할은 관찰 가능한 이라는 역할이죠.
즉, 스트림을 관찰합니다.

subscribe는 Observable의 스트림을 관찰하고 구독하고 값들을 받는 역할을 합니다.

저번 글에 썼던 코드를 다시 볼게요.

checkArrayEven(arr: [1, 3, 5, 7, 9])
    .subscribe { event in
    switch event {
    case .next(let value):
        print("next: \(value)")
    case .error(let error):
        print("error: \(error)")
    case .completed:
        print("completed!!")
    }
}/* .dispose(by: disposeBag)*/

이렇게 dispose객체를 반환해주지 않는다면 아래와 같은 경고문이 뜹니다.

Result of call to 'subscribe' is unused

이유는 subscribe객체는 disposable이라는 객체를 반환해줘야 해요.

disposable은 사용 후 버리는, 일회용의 라는 사전적 의미를 가지고 있다고 했죠?

그리고 error 메서드가 호출되면 complete메서드는 호출되지 않는다고도 했고요.

disposeBag은 이름그대로 Disposable 타입을 담을 수 있는 클래스입니다.
값을 다 방출하고 사용이 끝나면 메모리에서 해제시켜주는 역할을 합니다.
다시 말해 메모리 릭을 방지하게 해주기 때문에 매우 중요합니다.

Observable을 subscribe 할 때마다 dispose()하는 것은 좋지 않은 방법이라고 합니다.

따라서 disposeBag을 전역변수로 생성해서 사용하시는게 좋아요.

그럼 바로 예제 코드를 살펴볼게요.

enum ErrorResult: Error {
    case unknownError
}

Observable<String>.create { observer in
    observer.onNext("Hi")
    observer.onNext("안녕")
    
    observer.onError(ErrorResult.unknownError)
    observer.onCompleted()
    
    observer.onNext("Hello")
    
    return Disposables.create()
}.subscribe { event in
    print("onNext: \(event)")
} onError: { error in
    print("onError: \(error)")
} onCompleted: {
    print("onCompleted")
} onDisposed: {
    print("onDisposed")
}.disposed(by: disposeBag)

이렇게 작성한 뒤 실행하면 아래 결과를 얻습니다.

하지만 만약 error, complete 이벤트와 메모리에서 해제시켜주는 dispose까지 작성을 안한다면 어떻게 될까요?

Observable<String>.create { observer in
    observer.onNext("Hi")
    observer.onNext("안녕")
    
    // observer.onError(ErrorResult.unknownError)
    // observer.onCompleted()
    
    observer.onNext("Hello")
    
    return Disposables.create()
}.subscribe { event in
    print("onNext: \(event)")
} onError: { error in
    print("onError: \(error)")
} onDisposed: {
    print("onDisposed")
}// .disposed(by: disposeBag)

이렇게 stream이 종료되지 않고 dispose도 되지 않아요.
이 상황이 메모리릭이 발생했다고 합니다.

이렇게 subscribe, dispose의 역할에 대해 알아보았는데 타입 하나하나 확인해가면서 쓰느라 시간이 상당히 걸리네요...
다음부터는 operator 기능들에 대해 하나씩 살펴보겠습니다.

틀린 내용, 보완할 내용이 있으면 언제든지 지적해 주세요.

0개의 댓글