앞서 살펴보았던 예제들 말고도 조금 다른 예제들도 봐야 내가 이해할 것 같아서 조금 더 알아보도록 하겠다.
CurrentValueSubject 예제
// subject 생성
let currentValueSubject = CurrentValueSubject<String, Never>("기본값")
// subscriber1
currentValueSubject
.sink(receiveCompletion: { print("1 번째 completion: \($0)") },
receiveValue: { print("1 번째 value: \($0)") })
// subscriber2
currentValueSubject
.sink(receiveCompletion: { print("2 번째 completion: \($0)") },
receiveValue: { print("2 번째 value: \($0)") })
// subscriber3
currentValueSubject
.sink(receiveCompletion: { print("3 번째 completion: \($0)") },
receiveValue: { print("3 번째 value: \($0)") })
// 현재 Subscriber들에게 모두 보냄
currentValueSubject.send("두번째 값")
currentValueSubject.send(completion: .finished)
currentValueSubject.send("세번째 값")
print(currentValueSubject.value)
1. CurrentValueSubject<String, Never>("기본값") 을 통해서 currentValueSubject라는 subject를 생성함.
2. currentValueSubject.sink를 통해서(앞서 말했다시피 sink는 subsriber를 생성하는 메서드) 3개의 subscriber를 생성.
출력 결과:
1 번째 value: 기본값
2 번째 value: 기본값
3 번째 value: 기본값
2 번째 value: 두번째 값
1 번째 value: 두번째 값
3 번째 value: 두번째 값
2 번째 completion: finished
1 번째 completion: finished
3 번째 completion: finished
두번째 값
1. CurrentValueSubject는 생성할 때 초기값이 필요한데 위의 코드에서 나는 "기본값"을 초기값으로 주었기 때문에 각각의 subscriber에게 "기본값"이라는 string이 전달됨.
currentValueSubject.send("두번째 값")
2. 그 후 send() 통해 subject에게 "두번째 값"을 전달했기 때문에 각각의 subscriber들에게 "두번째 값"이라는 string이 전달됨.
currentValueSubject.send(completion: .finished)
3. send(completion: .finished)를 통해 completion 값을 전달
currentValueSubject.send("세번째 값")
print(currentValueSubject.value)
4. 3번 과정에서 completion에 .finished를 전달한 후에는 send를 통해 보내지는 값들은 모두 무시 되어서 "세번째 값"은 subject에 들어가지 않아 currentValueSubject.value의 값은 "두번째 값"이 출력되게 된다.
[결론]
subject를 subscribe하는 모든 subscriber에게 send를 통해서 값을 보내고, send메서드를 호출하면 currentValueSubject의 value라는 프로퍼티도 업데이트가 된다. 따라서 CurrentValueSubject에는 최신 값만 유지하고 있게 된다.
PassthroughSubject
PassthroughSubject는 CurrentValueSubject와 다르게 초기값이 필요하지 않다.
또한 최신 값을 저장하기 위한 공간도 필요없다.(CurrentValueSubject에는 value를 통해서 최신값이 출력 가능 했음)
따라서 만약 subscriber가 없거나 demand가 0이라면 값을 보내더라도 아무 일도 발생하지 않게 된다.
PassthroughSubject 예제
let passthroughSubject = PassthroughSubject<String, Never>()
let firstSubscription = passthroughSubject
.sink(receiveCompletion: { print("1번째 completion: \($0)") },
receiveValue: { print("1번째 value: \($0)")}
)
passthroughSubject.send("첫번째 값")
let secondSubscription = passthroughSubject
.sink(receiveCompletion: { print("2번째 completion: \($0)") },
receiveValue: { print("2번째 value: \($0)")}
)
passthroughSubject.send("두번째 값")
// 오류 발생
// print(passthroughSubject.value)
출력 결과:
1번째 value: 첫번째 값
1번째 value: 두번째 값
2번째 value: 두번째 값
결과값은 다음과 같다.
CurrentValueSubject, PassthroughSubject의 눈에 띄는 차이점은 최신 값 저장 유무정도라고 할 수 있을 것 같다.
다음 시간에는 실제 프로젝트에서 예제를 보는 시간을 가져보도록 하겠다!
참고 링크:
'iOS 개발 > Combine' 카테고리의 다른 글
[Combine] Operater란? (1) (1) | 2023.05.25 |
---|---|
[Combine] Publisher Future와 CompletionHandler의 차이 (0) | 2023.05.24 |
[Combine] Subject 정의 및 예제(2) (0) | 2023.05.18 |
[Combine] Publisher & Subscriber란?(1) (0) | 2023.05.16 |
[Combine] Combine 정의(0) (0) | 2023.03.02 |