일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- UICollectionViewListCell
- SwiftUI
- cellForRowAt
- UIListContentConfiguration
- RequestInterceptor
- observable
- IOS
- RxSwift
- Main Thread
- ReactiveX
- ContentMode
- QoS
- 개발블로그
- dispatchqueue
- alamofire
- Xcode
- interceptor
- SWIFT
- Moya
- observe(on:)
- 라이징캠프
- flatmap
- UIKit
- iOS교육
- distinctUntilChanged
- RxCocoa
- defaultContentConfiguration
- restfulAPI
- 컴공선배
- URLSession
- Today
- Total
RB의 iOS 개발 이야기
Observable과 Subject의 차이는 무엇인가? 본문
Observable vs Subject
Observable은 이벤트를 방출하는 역할을 담당하고 Observer는 Observable을 구독하며 이벤트를 받아서 처리하는 역할을 담당합니다.
여기서 Observable은 새로운 값을 받을 수 없다. 그렇다면 Observer 역할을 하는 녀석은 누구일까?
글의 제목에서 유추할 수 있듯이 Observer 역할을 하는 친구가 Subject입니다.
Subject의 RxSwift 문서를 확인해보면 Observable을 상속받고 있고 ObservavleType을 채택하고 있습니다.
그렇기에 정확히는 'Observer 역할을 하는 친구가 Subject이다.' 라는 말 보다는 'Observable과 Observer의 역할을 모두 가지고 있는 친구가 Subject이다.'가 더 맞는 표현이다!
Unicast vs Multicast
Observable과 Subject는 단순히 역할의 차이도 있지만 Unicast와 Multicast의 차이점을 알고 사용하면 더 효과적인 코드를 작성할 수 있을 것 입니다.
아래의 코드를 확인해보면
let number = Observable<Int>.create { observer in // 총 3번이 실행된다
observer.onNext(Int.random(in: 1...100))
return Disposables.create()
}
number.subscribe { value in
print("Number \(value)") // Number 24
}
.disposed(by: disposeBag)
number.subscribe { value in
print("Number \(value)") // Number 75
}
.disposed(by: disposeBag)
number.subscribe { value in
print("Number \(value)") // Number 48
}
.disposed(by: disposeBag)
상수 number는 Observable.create를 통해 랜덤 Int 값 방출하고 있는 상태입니다.
그 아래로 number를 구독하고 있는 코드가 있는데 구독을 할 때마다 새로운 스트림이 발생하여 각기 다른 값을 출력하고 있는 상황을 확인할 수 있습니다. 이것이 Unicast입니다. 이로인해 같은 Observable을 여러 곳에서 구독하게 된다면 자원의 낭비가 발생할 수 있습니다.
다음으로 Multicast는 단순하게 Unicast와 반대로 생각하면 편합니다.
let number = BehaviorSubject<Int>(value: Int.random(in: 1...100))
number.subscribe { value in
print("Subject \(value)") // Subject 20
}
.disposed(by: disposeBag)
number.subscribe { value in
print("Subject \(value)") // Subject 20
}
.disposed(by: disposeBag)
number.subscribe { value in
print("Subject \(value)") // Subject 20
}
.disposed(by: disposeBag)
Subject는 Multicast로 동작하기 때문에 여러번 구독을 하여도 하나의 스트림을 공유하게 됩니다.
그렇다면 Observable을 Muticast로 동작하게 할 수 있는 방법은 없는 것일까?
운이 좋게도 가능하다!
let number = Observable<Int>.create { observer in // 총 3번이 실행된다
observer.onNext(Int.random(in: 1...100))
return Disposables.create()
}.share()
number.subscribe { value in
print("Number \(value)") // Number 39
}
.disposed(by: disposeBag)
number.subscribe { value in
print("Number \(value)") // Number 39
}
.disposed(by: disposeBag)
number.subscribe { value in
print("Number \(value)") // Number 39
}
.disposed(by: disposeBag)
위의 Observable과의 차이점이 보이시나요?
바로 상수 number 마지막에 붙어있는 .share()가 차이점입니다.
share 메서드를 활용하게 되면 Observable을 여러 곳에서 구독하더라도 하나의 값으로 사용할 수 있습니다.
이렇게 오늘은 Observable과 Subject의 차이점을 알아보았고 .share()을 활용하는 방법까지 알아봤습니다! 감사합니다!
'iOS > RxSwift' 카테고리의 다른 글
Rx가 지원하는 스케줄러(schedulers)의 종류들 (0) | 2024.01.07 |
---|---|
Alamofire RequestInterceptor 사용해보기 (0) | 2023.12.14 |
App Store 검색 예제 구현중 발생한 메모리 누수 이슈 (0) | 2023.11.28 |