[Combine] Subject

도윤·2022년 12월 27일
0

Subject

SubjectPublisher의 한 종류

protocol Subject<Output, Failure> : AnyObject, Publisher

Publisher는 정의할 때 설정한 값만 방출하는 반면에 외부에서 값을 주입해줄 수 있다.

send(_:) 를 활용하여 값을 stream으로 주입할 수 있다.

Output뿐만 아니라 Completion을 주입할 수 있다.

send(completion: .finished)
send(completion: .failure(_)

RxSwift의 Subject와 비슷한 개념으로 보인다.

종류는 크게 **PassthroughSubject** 와 **CurrentValueSubject 가 있다.

둘의 큰 차이점은 가장 마지막에 방출한 버퍼를 유지하는지, 정의할 때 초기값을 정의하는 지 차이가 있다.

PassthroughSubject

final class PassthroughSubject<Output, Failure> where Failure : Error

정의할 때 initail value를 선언하지 않는다. RxSwift의 publishsubject와 동일한 개념으로 구독이후에 전달된 값만 방출된다.

let subject = PassthroughSubject<Int, Never>()
    
subject.send(1)
subject.send(2)

subject.sink {
    print($0)
} receiveValue: {
    print($0)
}

sink이전에 값을 send해줬다면 sink해도 아무런 값을 받지 못한다.

CurrentValueSubject

final class CurrentValueSubject<Output, Failure> where Failure : Error

PassthroughtSubject와 다르게, 정의할 때 초기값을 선언해야 하며 가장 최근에 방출된 값들이 버퍼에 남아있는다.

let subject = CurrentValueSubject<Int, Never>(0)
    
subject.send(1)
subject.send(2)

subject.sink {
    print($0)
} receiveValue: {
    print($0)
}

// 2

PassthroughtSubject는 Sink이전에 전달된 값은 전달받지 못하는데 CurrentValueSubject는 가장 최근의 버퍼를 유지하기 때문에 2를 전달받는다.

eraseToAnyPublisher

func eraseToAnyPublisher() -> AnyPublisher<Self.Output, Self.Failure>

subject들이 더이상 send로 값을 주입해주지 않는다면 subject는 오버 엔지니어링(?)되는 형태일 수 있다.

따라서 이렇게 eraseToAnyPublisher를 통해 AnyPublishser 형태로 만들어서 Subject였던 모습을 감추게 된다.

0개의 댓글