Combine) Subject

Havi·2021년 5월 17일
0

Combine

목록 보기
4/8

Subject

A publisher that exposes a method for outside callers to publish elements.

Subject란 외부의 caller가 요소를 방출할 수 있는 방법을 제공해주는 Publisher이다.

Publisher이니까 Publisher프로토콜을 준수하고 있는게 당연 ..

subject는 send(_:) 메소드를 통해 어떠한 stream에 값을 주입할 수 있는 publisher이다.
이것은 존재하는 명령형 코드를 adapting하는데 유용하다 (..?)

종류

Subject에는

  1. CurrentValueSubject
  2. PassthroughSubject

이렇게 두가지가 존재한다.

PassthroughSubject

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

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
*/

Type 삭제

let publisher: AnyPublisher<String, Never> = passthroughSubject.eraseToAnyPublisher()

이렇게 Type ErasereraseToAnyPublisher()를 활용할 경우 subject라는 사실을 숨겨 send로 값을 추가할 수 없게 만들어 줄 수 있다.

profile
iOS Developer

0개의 댓글