참고 : 데브루키 UniRX시작하기
https://www.slideshare.net/agebreak/160409-unirx
스트림의 구독(Subscribe)
- 스트림은 Subscribe 된 순간에 생성된다. (LINQ에서도 존재하는 특성)
- OnError나 OnComplete가 발생하면 구독이 종료된다.
- Subscribe는 오버로드로 정의되어있어 선택적으로 Action을 추가할 수 있다.
(기본형은 일반적인 메시지인 OnNext만 Action을 할당하게 되어있다.)
구독의 종료 시점
구독은 OnCompleted()가 호출될 때까지 지속된다.
1) 게임 오브젝트에 연결된 경우
- ObservableTriggers는 연결된 게임 오브젝트가 Destroy될 때 OnCompleted를 호출함.
2) 정적 스트림을 구독한 경우
- Observable.EveryUpdate 등과 같이 정적스트림은 자동으로 중지되지 않으며, 수동으로 관리해야 한다.
Observable.EveryUpdate().Subscribe(x => Debug.Log(x));
- 정적으로 스트림을 만든 경우에도 AddTo로 오브젝트에 연결시켜놓으면, 오브젝트가 삭제될 때 Dispose된다.
Observable.IntervalFrame(30).Subscribe(x => Debug.Log(x)).AddTo(this);
3) 오퍼레이터를 통해 완료 조건을 설정한 경우
- TakeWhile, TakeUntil, TakeUntilDestory 등과 같이 조건을 만족시키면 OnCompleted가 호출된다.
- 그러나 Repeat를 같이 사용한 경우 무한 루프가 발생할 수 있으니 주의할 것.
4) 감시 대상이 일반 C# 객체일 경우
- GC에 의해 Dispose()될 때 OnCompleted가 호출됨
5) 직접 Dispose된 경우
- IDisposable 인터페이스의 Dispose()를 호출할 경우 직접 구독을 종료하게 된다.
- 이때는 OnCompleted()가 호출되지 않으니 주의할 것.
IDisposable disposable = button1.onClick
.AsObservable()
.Subscribe(_ => text.text = "클릭");
disposable.Dispose();
이미 Completed가 호출된 Subject
이미 OnCompleted()가 통지된 Subject는 재사용이 불가능하며,
Subscribe를 호출해도 바로 OnCompleted가 발행된다.
IEnumerator Start()
{
Subject<int> mySubject = new Subject<int>();
mySubject.AsObservable()
.Subscribe(n => Debug.Log(n),
() => Debug.Log("종료됨"));
mySubject.OnNext(0);
yield return new WaitForSeconds(0.5f);
mySubject.OnCompleted();
yield return new WaitForSeconds(0.5f);
mySubject.AsObservable()
.Subscribe(n => Debug.Log(n),
() => Debug.Log("종료됨"));
yield return new WaitForSeconds(0.5f);
mySubject.OnNext(1);
}
특정 구독만 종료하기
- 하나의 Subject에 여러개의 구독이 실행되고 있을 경우 Subject.OnCompleted()를 통해 전체 구독을 종료할 수 있다.
- 만일 특정 구독만 종료하고 싶다면 IDisposable 인터페이스의 Dispose()를 실행하면 된다.
- 단, 이 경우 OnCompleted()가 호출되지 않는다.
public Subject<int> mySubject = new Subject<int>();
IEnumerator Start()
{
IDisposable disposalA = mySubject.Subscribe(
_ => Debug.Log("A"),
() => Debug.Log("A Completed"));
IDisposable disposalB = mySubject.Subscribe(
_ => Debug.Log("B"),
() => Debug.Log("B Completed"));
StartCoroutine(MyCoroutine());
yield return new WaitForSeconds(1f);
disposalA.Dispose();
}
IEnumerator MyCoroutine()
{
while(true)
{
yield return new WaitForSeconds(0.8f);
mySubject.OnNext(0);
}
}
- 위 예제에서 mySubject.Dispose()시 -> 두 개의 구독이 OnCompleted없이 종료
- mySubject.OnCompleted()시 -> 두 개의 구독이 OnCompleted를 발생시키며 종료
mySubject.OnCompleted();
'🌍 Unity 연구 > UniRX' 카테고리의 다른 글
UniRX 배우기 6) UniRX 오퍼레이터 (0) | 2021.04.30 |
---|---|
UniRX 배우기 5) 코루틴과 함께 사용하기 (0) | 2021.04.29 |
UniRX 배우기 4) Hot, Cold Observable (0) | 2021.04.29 |
UniRX 배우기 2) Observable 객체 생성하기 (0) | 2021.04.25 |
UniRX 배우기 1) 스트림과 메시지 (0) | 2021.04.23 |