A publisher that exposes a method for outside callers to publish elements.
Subject란 외부의 caller가 요소를 방출할 수 있는 방법을 제공해주는 Publisher이다.
Publisher이니까 Publisher
프로토콜을 준수하고 있는게 당연 ..
subject는 send(_:)
메소드를 통해 어떠한 stream에 값을 주입할 수 있는 publisher이다.
이것은 존재하는 명령형 코드를 adapting하는데 유용하다 (..?)
Subject에는
이렇게 두가지가 존재한다.
PassthroughSubject는 downstream 구독자들에게 요소를 방출하는 broadcast역할을 한다.
구독자가 없거나 demand가 0이면 값을 drop한다.
let passthroughSubject = PassthroughSubject<String, Never>()
let sub1 = passthroughSubject.sink {
print("sub1: ", $0)
}
let sub2 = passthroughSubject.sink {
print("sub2: ", $0)
}
passthroughSubject.send("passthrough send")
passthroughSubject.send("passthrough send222")
sub1.cancel()
passthroughSubject.send("sub1 구독 해제 sub2만 남아있음")
passthroughSubject.send(completion: .finished)
passthroughSubject.send(".finished 호출하면 이 값은 전달 안됨!")
/*prints
sub1: passthrough send
sub2: passthrough send
sub1: passthrough send222
sub2: passthrough send222
sub2: sub1 구독 해제 sub2만 남아있음
*/
CurrentValueSubject는 단일 값을 wrapping하며, 값이 바뀔 때 마다 새로운 요소를 방출한다.
PassthroughSubject와 다르게 가장 최근에 방출된 요소를 버퍼에 저장한다.
CurrentValueSubject에서 send를 호출할 경우, 현재 값도 업데이트 되므로 값을 직접 업데이트 하는 것과 같다.
let currentSubject = CurrentValueSubject<String, Never>("This is Initial Value")
let subscriber = currentSubject.sink {
print($0)
}
// 값을 바꾸면 send하는 것 처럼 호출된다.
currentSubject.value = "This is Value"
currentSubject.send("This is send")
/* prints
This is Initial Value
This is Value
This is send
*/
let publisher: AnyPublisher<String, Never> = passthroughSubject.eraseToAnyPublisher()
이렇게 Type Eraser인 eraseToAnyPublisher()
를 활용할 경우 subject라는 사실을 숨겨 send로 값을 추가할 수 없게 만들어 줄 수 있다.