ConnectablePublisher
connecting, canceling의 명시적인 의미를 가진 publisher
subject와 같이 publisher의 일부입니다.
element를 생산하기 전 추가적인 configuration, setup을 수행할 필요가 있을때, ConnectablePublisher를 사용합니다.
connect() 메소드 호출 전, publisher는 어떤 element도 생산하지 않습니다.
makeConnectable()을 사용하여 ConnectablePublisher을 생성합니다.
private func connectablePublisher(){
let publisher = ["hi", "hello"].publisher.makeConnectable()
let cancellable = publisher.sink(receiveValue: { print($0) })
publisher.connect()
}
publisher.connect()를 호출하기 전까진 아무 값도 방출되지 않다가 publisher.connect() 호출시
값이 방출됩니다.
private func connectablePublisher(){
let publisher = ["hi", "hello"].publisher.makeConnectable().autoconnect()
let cancellable = publisher.sink(receiveValue: { print($0) })
}
autoconnect()를 사용하는 방식도 있습니다. 이때엔 자동으로 connect가 호출됩니다. 출력은 위의 결과와 같습니다.
하지만 sink 밑에서 publisher.autoconnect()시 publisher.connect()와 달리 출력되지 않습니다.
private func connectablePublisher(){
let publisher = ["hi", "hello"].publisher.makeConnectable()
let cancellable = publisher.sink(receiveValue: { print($0) })
publisher.autoconnect()
}
여기까지 생각해보았을때, publisher가 구독하고 있는 subscriber에게 값 방출하는 것을 지연시키거나 특정 시간으로 지정할 수 있어보입니다. 하지만 subscriber가 1개 있을때에는 왜 사용해야 하는지, 어떤 경우에 사용되는지 잘 감이 오지 않습니다 🤔
그래서 아래 글을 참고하게 되었습니다.
https://developer.apple.com/documentation/combine/controlling-publishing-with-connectable-publishers
https://zeddios.tistory.com/1009
URLSession.dataTaskPublisher할 경우입니다.
publisher를 구독하고 있는 subscriber가 여럿이 있을때, 경쟁 조건(race condition)을 만들 수 있습니다. 두번째 subscriber가 생성되어 값을 구독 받기 전 첫번째 subscriber에게 값 방출이 일어날 수 있을 것입니다.
각각 publisher를 구독하는 subscriber1, subscriber2가 있다고 가정해 봅시다.
URLSession.dataTaskPublisher를 생성하고 subscriber1에 sink를 붙였을때 URL data가 fetch되기 시작합니다. 그 후에 subscriber2에 sink를 붙였을때, 만약 data task가 subscriber2가 붙여지기 전 데이터 다운로드를 완료했다면 subscriber2는 데이터를 못받고 오로지 completion만 방출하게 될 것입니다.
subscriber2도 값을 가질 수 있도록 보장하기 위해 ConnectablePublisher이 유용합니다.
ConnectablePublisher은 명시적으로 connect를 호출하기 전까지 subscriber에게 어떤 element도 방출하지 않습니다. 따라서 subscriber1과 subscriber2가 붙여지고 connect()를 호출하게 되면 두 subscriber는 모두 데이터를 받고 경쟁조건이 발생하지 않음을 보장할 수 있게됩니다.
또한 Timer에도 유용합니다.
autoconnect()를 사용한다면 subscriber가 있을때, 즉시 connect()를 호출합니다.
'IOS🍎 > Combine' 카테고리의 다른 글
[Combine] Cancellable이란 (0) | 2023.04.17 |
---|---|
[Combine] Scheduler란 (0) | 2023.04.16 |
[Combine] Subject란 (AnyPublisher) (0) | 2022.04.17 |
[Combine] Combine, Publisher, Subscriber 에 대해서 (0) | 2022.04.17 |
댓글