Combine 뽀개기 3장: Subject

2023. 7. 26. 20:02·iOS&Swift

Subject

A publisher that exposes a method for outside callers to publish elements.
외부 호출자가 요소를 게시할 수 있도록 메서드를 노출하는 게시자입니다.

Subject또한 프로토콜이다. Subject도 쉽게 생각하면, publisher의 한 종류이다.

protocol Subject : AnyObject, Publisher

왜냐하면, Subject 또한 publisher를 채택받고 있기 때문이다.

자그럼 둘은 무슨 차이냐!

일반 publisher 같은 경우 선언과 동시에 방출될 값이 정해진다.

예를 들어, Just 같은 경우에도

let justPublisher = Just("Combine 첫 교시")

정해진 "Combine 첫 교시"라는 값 밖에 방출하지 못한다.

다른 여타 publisher도 형태만 다를 뿐이지 선언과 동시에 정해진 값 밖에 방출하지 못하는 것은 같다.

또한 값을 모두 방출하면, 자동적으로 completion이 호출된다.

하지만, Subject 같은 경우 추가적인 요소를 방출할 수 있다.

자세한 사용법은 코드로 확인하고, 그전에 구현되어 있는 Subject 소개하자면, 두개가 존재한다.

  • CurrentValueSubject
  • PassthroughSubject

둘의 차이는 "초기값이 있냐, 없냐"의 차이이다.

CurrentValueSubject

CurrentValueSubject 이녀석은 초기값이 있는 Subject

var subscriberBag = Set<AnyCancellable>()

let currentValueSubject = CurrentValueSubject<String, Never>("Safari")

currentValueSubject.sink { completion in
    print(completion)
} receiveValue: { value in
    print(value)
}.store(in: &subscriberBag)
Safari

위와 같이 CurrentValueSubject는 생성자에 초기값을 넣어줘야 한다.

실행해보면, Safari 호출되고 completion이 호출되지 않는 것을 볼 수 있다.

이는 아직 CurrentValueSubject의 작업이 끝나지 않았음을 알 수 있다.

currentValueSubject.value = "Combine"
currentValueSubject.send("swift")

위 코드를 아래에 추가하면,

Combine
swift

위와 같이 값을 추가로 방출하는 것을 볼 수 있다.

이번엔,

currentValueSubject.send(completion: .finished)
currentValueSubject.send("Rxswift")

위 같이 코드를 추가하면,

finished

finished가 호출되고 더이상 "Rxswift"라는 값은 방출하지 않는다.

이는 completion를 통해 작업이 끝났음을 선언했기 때문이다.

위와 같이 Subject 같은 경우 send 메서드를 통해 추가적인 값 방출이 가능하다

전체 코드,

var subscriberBag = Set<AnyCancellable>()
let currentValueSubject = CurrentValueSubject<String, Never>("Safari")// 필수적으로 초기값이 필요

currentValueSubject.sink { completion in
    print(completion)
} receiveValue: { value in
    print(value)
}.store(in: &subscriberBag)


currentValueSubject.value = "Combine"
currentValueSubject.send("swift")
currentValueSubject.send(completion: .finished)
currentValueSubject.send("Rxswift")
Safari
Combine
swift
finished

PassthroughSubject

PassthroughSubject같은 경우 currentValueSubject 보다 심플하다.

따로 초기값이 없기 때문이다.

enum InputError: Error {
    case unkown
}

let passthroughSubject = PassthroughSubject<String, InputError>()

passthroughSubject.sink { result in
    switch result {
    case .finished:
        print("input 끝")
    case .failure(let error):
        print(error.localizedDescription)
    }
} receiveValue: { value in
    print(value)
}.store(in: &subscriberBag)

위와 같이 생성자에 초기값이 들어가지 않는다.

passthroughSubject.send("m1Mac")
passthroughSubject.send("사고싶다.")

때문에 위와 같이 send 메서드를 통해 보낸 값만을 방출한다.

m1Mac
사고싶다.

또한, send(completion:) 메서드는 .finished만 보내는것이 아닌 Subject가 Error를 방출한다면,

passthroughSubject.send(completion: .failure(.unkown))

passthroughSubject.send("더이상 input를 받지 않음")

.failure를 통해 Error 방출이 가능하다.

unkown

역시 completion이 호출되었기 때문에 아래의 "더이상 input를 받지 않음"이라는 값을 방출하지 않는다.

전체 코드,

var subscriberBag = Set<AnyCancellable>()

enum InputError: Error {
    case unkown
}

let passthroughSubject = PassthroughSubject<String, InputError>()

passthroughSubject.sink { result in
    switch result {
    case .finished:
        print("input 끝")
    case .failure(let error):
        print(error)
    }
} receiveValue: { value in
    print(value)
}.store(in: &subscriberBag)

passthroughSubject.send("m1Mac")
passthroughSubject.send("사고싶다.")

passthroughSubject.send(completion: .failure(.unkown))
//passthroughSubject.send(completion: .finished)

passthroughSubject.send("더이상 input를 받지 않음")
m1Mac
사고싶다.
unkown
저작자표시 (새창열림)

'iOS&Swift' 카테고리의 다른 글

[Swift] Alamofire의 RequestInterceptor을 사용해 토큰 갱신하기  (0) 2024.01.18
Combine 뽀개기 4장: Scheduler  (0) 2023.07.26
Combine 뽀개기 2장: Subscriber  (0) 2023.07.26
Combine 뽀개기 1장: Publisher  (0) 2023.07.26
Appearance사용해 NavigationBar 커스텀하기(iOS 13.0+)  (0) 2023.07.19
'iOS&Swift' 카테고리의 다른 글
  • [Swift] Alamofire의 RequestInterceptor을 사용해 토큰 갱신하기
  • Combine 뽀개기 4장: Scheduler
  • Combine 뽀개기 2장: Subscriber
  • Combine 뽀개기 1장: Publisher
Esiwon
Esiwon
iOS 개발 블로그
  • Esiwon
    시원한 코드 기록
    Esiwon
  • 전체
    오늘
    어제
    • 분류 전체보기 (70)
      • iOS&Swift (24)
      • git & github (1)
      • 코테 (41)
      • 네부캠 회고 (4)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • 깃허브
  • 공지사항

  • 인기 글

  • 태그

    그리디
    BFS
    실버
    dfs
    챌린지
    Swift
    Property wrapper
    구현
    Race Condition
    알고리즘
    회고
    노드
    ios
    코딩테스트
    코테
    photos
    네부캠
    이분탐색
    비동기
    완전탐색
    Combine
    동시성
    탐색
    photoUI
    GCD
    PhotoKit
    다이나믹 프로그래밍
    재귀
    백준
    브루트포스 알고리즘
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Esiwon
Combine 뽀개기 3장: Subject
상단으로

티스토리툴바