본문 바로가기
Swift

[iOS] About RxSwift

by dsungc 2024. 8. 11.

이번 글에서는 그냥 RxSwift 주요 키워드들을 주저리 주저리 제 의식의 흐름따라 읊어보고자 합니다.

용어들이 너무 생소하기에..

처음 보는 아이들과 익숙해지고 친해지기 위함이죠 😁

Observable   

이벤트를 전달(방출) 하는 아이

그럼 그 이벤트에는 뭐가 있냐??

 

1. onNext

2. onComplete

3. onError

4. onDisposed

 

이렇게 총 네 네가지 입니다.

 

보통 위 네가지 이벤트를 유튜브에 빗대어 많이들 표현하시더라구요!

저도 한 번 해볼까 합니다. ㅋ.ㅋ

 

우선 onNext는 새로운 이벤트가 방출 되는 것이기 때문에, 유튜브에 영상 업로드가 되겠죠?

onComplete는 더이상 방출될 요소가 없는 것이기에, 유튜버가 유튜브를 그만하는 상황으로 보시면 됩니다.

onError는 오류로 인하여 이벤트를 확일할 수 없는 것이고, onDisposed는 유튜브 채널이 삭제된 상황이에요!

중요한 것은 이 친구는 오직 "방출" 만 가능해요!!

 

Observer

이벤트를 처리 하는 아이

다들 Observable은 생소할지라도 Observer는 어렸을 때부터 자주 보셨죠?

뜻 그대로, 계속 보는 친구에요. 계속 보다가 이벤트가 생기면 처리해준다고 보시면 됩니다.

이 친구는 Observable과 반대로 이벤트를 "처리" 하는 것만 가능합니다.

IF

자 그렇다면 이 두 친구의 관계에 대해 살펴보기 위해 만약에~ 놀이를 좀 해보려고 합니다.

 

- Observer가 없다면? 👉 백날 버튼 눌러봐야 아무런 일도 일어나지 않겠죠?

- Observer가 없어진다면? 👉 처리해왔떤 이벤트들을 앞으로는 처리할 수 없게 됩니다.

- 처음엔 Observer가 없다가 나중에 생긴다면? 👉 이벤트를 처리할 수 없다가 Observer가 생긴 이후에 이벤트를 처리할 수 있습니다.

 

기본적으로 Observable이 Observer를 구독하는 형태이고 작업이 끝나면 disposed 된답니다. 

 

Dispose

자, 그럼 여기서 자연스럽게 disposed 이야기로 넘어가볼게요.

 

disposed는 Observable의 생명 주기가 끝났을 때 리소스(예: 메모리, 네트워크 연결 등)를 해제하는 역할을 합니다.

만약, 방출이 유한한 이벤트라면, 

Emit Finite > Complete > disposed > Sequence Quit 의 순서를 거치게 되는거죠.

 

그럼 어떻게 dispose가 되게 하냐? 그냥 있으면 되냐? 그건 아니고 여기서 우리는 DisposeBag을 사용합니다.

let disposeBag = DisposeBag()

observable
    .subscribe(onNext: { value in
        print("Received value: \(value)")
    })
    .disposed(by: disposeBag)

 

 

이런식으로요!

유한한 방출의 경우 위와 같은 방법으로 disposed 되고, 무한한 방출의 경우는 뷰컨트롤러가 기본적으로 DisposableBag()을 갖고 있기 때문에 VC의 클래스가 잘 deinit이 된다면 리소스 정리가 알아서 이루어진답니다. 걱정 안 하셔두 되요~

 

아 참고로 RootViewController의 경우는 메모리에서 dispose되지 않기 때문에 이 점 꼭 기억해야합니다.

 

자 그렇다면 Observable과 Observer의 역할을 모두 하는 친구는 없을까..? 하는 생각이 드는데요

역시.. 있습니다. 없을리가 없죠

 

그 친구는 바로 Subject라는 친구인데요, Observable이 전달만 한다면, 이 친구는 전달과 실행의 기능을 모두 담당합니다.

그런데 이 Subject도 역시 종류가 있습니다.

 

바로 BehaviorSubject, PublishSubject, ReplaySubject, AsyncSubject 인데요, 하나씩 가보자구요

(AsyncSubject는 한 번도 사용해본 경험이 없어서 Pass....😂)

 

 

 

PublishSubject

- 초기값 X

- 이벤트가 일어날지라도 구독 이후의 일어난 이벤트만 전달

- 단발성 이벤트에 적합 > 버튼 클릭

 

BehaviorSubject

- 초기값 O

- 구독이 일어날 경우 갖고 있던 초기값을 즉시 전달

- 초기값을 넣어준 시점 이후에 이벤트가 발생되면, 구독 바로 이전의 이벤트를 전달

- 뷰를 미리 채워두거나 UI상태를 유지해야할 때 사용

 

ReplaySubject

이 부분은 말로 풀어서 설명해보려고 합니다. 

이 친구는 bufferSize라는 것을 동반하여 사용합니다. bufferSize는 개수를 나타내는 정수값인데요.

bufferSize가 2 라고 하면, 구독 이전의 두 개의 이벤트를 전달 받는 것이죵.

실생활로 예를 들어보자면, 우리 세상에서는 셀프 사진관을 가서 사진을 찍으면 8장 정도 찍고 4장의 사진을 선택합니다. 그죠?

그런데 이 친구들 세상에선 bufferSize, 즉 몇 장의 사진을 받을 것인지 정합니다.

그러고 총 8장의 사진을 찍었을 때, 시간 순서대로 1번~8번까지 있을텐데요. 만약 bufferSize가 2다?

그럼 7,8번 사진만 받아오는 거에요.

어? 나 1번 사진 받고 싶은데? 그러면 bufferSize가 8이 되어야만 하는것이죠.

그럼 위의 마블 다이어그램은 bufferSize가..? 

.

.

2 인겁니다. 

 

그럼 Subject는 여기서 끝... 이 아니라

 

Relay

Relay는 RxSwift에서 제공하는 특별한 형태의 Subject로, Side Effect 없는 상태 관리와 UI 바인딩에 자주 사용됩니다.

특히 이벤트가 자동으로 종료되거나 에러가 발생하지 않도록 설계되어 있어, 이벤트 스트림을 단순히 지속하고 싶은 경우에 적합합니다.

 

Relay는 Subject와 마찬가지로 Pusblish, behavior가 있습니다.

  1. PublishRelay: 구독자가 없으면 이벤트를 버리고, 구독자가 있을 때만 이벤트를 전달하는 Relay입니다.
  2. BehaviorRelay: 가장 최근의 값을 저장하고, 새로운 구독자에게 그 값을 즉시 전달하는 Relay입니다. 구독 시점에 관계없이 마지막으로 전달된 값을 받을 수 있습니다.

Relay는 에러 이벤트와 완료 이벤트가 없으며, 이러한 특성 덕분에 UI와 바인딩할 때 예측 가능한 동작을 유지할 수 있습니다.

기본적으로 Relay는 무한한 생명 주기를 가지며, 종료나 에러가 발생하지 않는 것이 특징입니다.

 

 

Observer & Observable / Subject에 관련해서 주저리주저리 해봤는데요

꽤 많이 용어를 적어본 것 같지만 아직 한참... 남아있다는 사실🤣

이번 글은 여기까지지만 다음에 다른친구들을 데리고 한 번 더 주저리 주저리 해보겠습니다.

그럼 이만

.

.

.

.

'Swift' 카테고리의 다른 글

[iOS] About Pagination  (0) 2024.08.21
[iOS] About Subscribe, Bind, Driver + @  (0) 2024.08.17
[iOS] About 램 모델클래스 > 구조체  (0) 2024.08.08
[iOS] About Property Wrapper  (0) 2024.08.04
[iOS] About FsCalendar - 2  (0) 2024.07.20