본문 바로가기
IOS🍎/Combine

[Combine] ConnectablePublisher

by Jouureee 2022. 5. 3.

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

 

Apple Developer Documentation

 

developer.apple.com

https://zeddios.tistory.com/1009

 

Combine ) ConnectablePublisher

안녕하세요 :) Zedd입니다. Combine도 계속 공부해야하는데..!!!! @_@ ConnectablePublisher는 그냥 눈에 띄길래...공부해보려고 합니다. ConnectablePublisher ConnectablePublisher은 프로토콜입니다! 아오 프로..

zeddios.tistory.com

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

댓글