Observable / Observer

비동기 이벤트에 대해 관찰 가능할 순차적인 형태가 Observable이고 해당 이벤트의 변화를 관찰하여 전파를 받는 대상이 Observer이다. Observable은 이벤트를 전달하고 Observer는 이를 감시하고 있다가 전달되는 이벤트를 처리한다. 이때 서로 다른 개체에 공통으로 데이터들을 주고 받을 수 있는 공간을 이벤트라고 한다. 이러한 이벤트에는 단순한 값 뿐만이 아니고 사용자 인터렉션 등도 포함이된다. RxSwift에서는 비동기적으로 관찰 가능한 이벤트를 이용하여 정보들으 주고 받는다.

Observable의 Event

Next

새로운 이벤트가 발생하면 이 Next 이벤트를 통해서 정보를 전달한다. 이러한 과정을 Emission이라고 하며 일반적으로 우리는 Next 이벤트를 통해 새로운 이벤트 발생시점에 새로운 값을 포함하여 데이터를 처리한다.

Error

Observable에서 에러가 발생하면 Observable의 라이프 사이클 가장 마지막에 Error 이벤트가 전달이된다. 이후 Observable이 종료되고 이러한 과정은 Emission이 아닌 Notification이라고 한다.

Completed

Observable이 정상적으로 종료되면 Completed 이벤트가 전달된다. Completed 이벤트 역시 Emission이 아닌 Notification이라고 한다.

Observable 생성방법

just

하나의 항목을 방출하는 Observable Sequence를 생성한다. 파라미터로 넘어온 데이터를 한번 방출하고 completed가 불려서 dispose 된다. Observable을 구독하는 시점에 파라미터로 받은 데이터를 방출하고 배열같은 컬렉션을 파라미터로 넘기면 해당 컬렉션 자체를 방출한다. 하지만 여러개의 단일 데이터를 파라미터로 넘겨줄 수는 없다.

of

하나 이상의 항목을 방출하는 Observable Sequence를 생성한다. 파라미터가 가변적이기 때문에 방출을 원하는 데이터를 모두 넘겨주면 해당 데이터들을 하나씩 방출하고 completed가 불려서 dispose 된다. 이때 넘겨주는 파라미터들의 타입은 동일해야한다. 이때도 배열같은 컬렉션을 파라미터로 넘기면 해당 컬렉션 자체를 방출한다. 대신 just와의 차이라면 여러개의 배열을 파라미터로 넘겨줄 수 있다는것?

from

하나의 배열을 파라미터로 받고 배열의 요소들을 순서대로 방출하는 Observable Sequence를 생성한다. 파라미터로 받은 배열을 순회하여 원소들을 하나씩 방출하고 completed가 불려서 dispose 된다.

create

Observer를 파라미터로 받는 클로저를 파라미터로 받는(?) Observable Sequence를 생성한다. 파라미터로 전달받은 Observer의 onNext, onCompleted, onError를 직접 호출할 수 있으며 클로저가 끝나기 전에 반드시 onCompleted나 onError를 딱 한번 호출해야 한다. 클로저 내에서 onCompleted나 onError를 호출한 이후에도 onNext를 호출할 수는 있지만 동작하지 않는다. 리턴타입은 Disposable이기 때문에 반드시 클로저 내에서 Disposable을 생성해서 리턴 해줘야한다.

return Disposables.create()

empty

아무 이벤트도 방출하지 않고 즉시 completed를 호출하여 종료되는 Observable Sequence를 생성한다. onNext가 불리지 않고 바로 onCompleted가 불리므로 특정 조건에 따라 Observable이 이벤트를 방출하지 않아야 할 때 사용할 수 있다. 또한 여러 Observable 중 하나를 선택해야 하지만 어떤 것도 선택되지 않은 경우에 디폴트값을 설정할 수도 있으며 특정 조건이 만족될 때까지 기다렸다가 그 조건이 만족되면 작업을 종료하고 싶은 경우에도 사용할 수 있다.

never

아무 이벤트도 방출하지 않고 스트림이 종료되지도 않는 Observable Sequence를 생성한다. 직접 dispose 하기 전까지는 절대 스트림이 종료되지 않기 때문에 메모리 해제를 고려하고 사용하여야 한다. 사용자 입력을 받는 동안 특정 버튼의 상호작용을 비활성화하는 것처럼 UI에서 특정 이벤트를 무시하고 싶을때 사용하거나 특정 조건을 충족할 때까지 다음 단계로 넘어가지 않게 하고 싶을 때 사용할 수 있다.

range

특정 범위의 ‘정수’를 순서대로 방출하는 Observable Sequence를 생성한다. 해당 범위 안의 정수를 모두 발행하면 onCompleted가 불리고 스트림이 종료된다. Observable이 방출하는 타입이 Int 고정이라는걸 인지해야한다.

interval

주어진 시간 간격마다 순서대로 정수를 방출하는 Observable Sequence를 생성한다. 직접 dispose를 하기 전까지는 이벤트를 무한으로 방출하므로 주의해야한다. range와 동일하게 방출하는 타입은 Int 고정이다.

timer

구독 시점으로부터 일정 시간 지연 후에 이벤트를 방출한 뒤 onCompleted가 호출되며 스트림이 종료되는 Observable Sequence를 생성한다. 첫번째 파라미터로는 지연 간격을 넘겨 받고 두번째 파라미터로는 다음 방출 주기를 넘겨 받는다. period를 사용하는 경우 일정 주기로 무한히 이벤트를 방출하기 때문에 직접 dispose 해줘야 스트림이 종료된다.

defer

Observer가 구독할 때까지 지연하고 구독이 시작될때 Observable Sequence를 생성한다. Observer가 구독을 하는 시점에 이벤트를 방출한다. 구독전에는 Observable이 생성되지 않기때문에 구독하는 Observer 별로 새로운 Observable이 생성된다.

Disposable / dispose()

subscribe로 Observable을 구독을 할 경우 더이상 구독이 필요하지 않을때 구독을 취소할 수 있는 수단으로 Disposable이란 타입의 값을 리턴한다. 즉 이 Disposable에 dispose() 메소드를 호출하면 구독한 Observable에 대해 구독을 해제할 수 있다. 이렇게 dispose 메소드를 실행하는 이유는 원하는 시점에 구독을 종료하기 위함도 있지 만 무엇보다 메모리 관리를 위해서 실행하는 것 이다. Observable은 complete나 error 이전에는 끊임없이 이벤트를 방출하므로 이벤트가 방출되지 않는 시점에 직접 구독을 해제해줘야한다.
Disposable 인스턴스의 dispose 메소드 호출 = Observable에 대한 리소스를 deinit
더이상 해당 인스턴스가 사용되지 않는 시점에 dispose 메소드를 호출하거나 VC가 deinit 될때 Observable 리소스도 dispose 해준다면 이러한 문제를 방지할 수 있다.

DisposeBag

Disposable 객체를 담는 배열로 disposed(by:) 메소드를 사용하여 미리 선언해놓은 DisposeBag 객체를 파라미ㄴ터로 넘겨주면 해당 DisposeBag에 Disposable들이 담기게 된다. 이 방법을 사용하면 선언해놓은 DisposeBag 객체가 사라질때 (= DisposeBag 객체를 가지고있는 Class가 Deinit될때) 내부에 있는 dispose() 메소드를 호출하여 배열에 담긴 Disposable들을 일괄적으로 해제한다. 따라서 전역변수로 선언해놓은 DisposeBag에 disposed(by:) 메소드를 사용하여 Disposable 객체들을 담아준다면 따로 despose 메소드를 호출하지 않고 사용해도 메모리 누수가 나지 않는다!!

댓글남기기