Subject

  • Observable이자 Observer이다.
  • .next(value)를 받고, 수신할 때마다 Subscriber에게 방출한다.
  • Sequence가 종료된 Subject를 subscription할 경우, 마지막 Event(.error 혹은 .completed) 를 방출한다.
  • Sequence가 종료된 Subject에 대하여 dispose를 호출하면 오류가 출력된다.

Relay와의 차이점

  • Relay는 completeerror를 받지 않는다.
  • Relay는 observable이 종료되어도, relay 내의 subject 종료되지 않는다.
    • 따라서, observable의 종료가 절대적으로 보장되지 않는다면, relay.bind 하는 것은 바람직하지 않다.

PublishSubject

  • 초기값이 존재하지 않으며, 새로운 값만을 Subscriber에게 방출한다.
let disposeBag = DisposeBag()
let subject = PublishSubject<String>()
subject.on(.next("Before subscribed"))

// Subscription 1
subject.subscribe {
    print("🟢", $0)
}

subject.on(.next("1"))
subject.on(.next("2"))

// Subscription 2
subject.subscribe {
    print("🔴", $0)
}

subject.on(.next("3"))
subject.on(.error(CustomError.error))
subject.on(.next("After error"))

// Subscription 3
subject.subscribe {
    print("🟡", $0)
}.disposed(by: disposeBag)

subject.on(.next("4"))

BehaviorSubject

  • 하나의 초기값을 갖으며, 새로운 Subscriber에게 초기값 또는 최신 값을 방출한다.
let disposeBag = DisposeBag()
let subject = BehaviorSubject<String>(value: "Initial value")
subject.on(.next("Before subscribed"))

// Subscription 1
subject.subscribe {
    print("🟢", $0)
}

subject.on(.next("1"))
subject.on(.next("2"))

// Subscription 2
subject.subscribe {
    print("🔴", $0)
}

subject.on(.next("3"))
subject.on(.error(CustomError.error))
subject.on(.next("After error"))

// Subscription 3
subject.subscribe {
    print("🟡", $0)
}.disposed(by: disposeBag)

subject.on(.next("4"))

ReplaySubject

  • 버퍼 사이즈 만큼의 값들을 유지하며, 새로운 Subscriber에게 버퍼 사이즈만큼 값을 방출한다.
  • 버퍼는 메모리에 할당되어져 있기 때문에, 이미지와 같이 큰 용량의 것을 버퍼로 갖지 않도록 한다.
  • .error 가 발생하여도 우선 버퍼에 있는 값들은 전달된다.
let disposeBag = DisposeBag()

let subject = ReplaySubject<String>.create(bufferSize: 2)
subject.on(.next("Before subscribed"))

// Subscription 1
subject.subscribe {
    print("🟢", $0)
}

subject.on(.next("1"))
subject.on(.next("2"))
subject.on(.next("3"))

// Subscription 2
subject.subscribe {
    print("🔴", $0)
}

subject.on(.next("4"))
subject.on(.error(CustomError.error))
subject.on(.next("After error"))


// Subscription 3
subject.subscribe {
    print("🟡", $0)
}.disposed(by: disposeBag)

subject.on(.next("5"))

AsyncSubject

  • .comleted되어야만 값이 나온다.
  • .completed 이전의 event에 대해서는 어떠한 것도 방출하지 않는다.
    • subscribe하여도 마찬가지로 .comleted 되기 전 까지는 아무런 값을 방출하지 않는다.
  • 종료 이벤트를 받으면 .next(lastElement) + .completed 를 방출한다.
  • 종료된 이후에 subscribe할 경우, .next(lastElement) + .completed 를 받게 된다.
  • 만약 값이 없이 그냥 .completed된 경우는 값 없이 그냥 completed만 받게 되며, error의 경우에는 .error를 받게 된다.
let subject = AsyncSubject<Int>()
subject.onNext(0)
subject.onNext(1)

subject.debug("🟢")
    .subscribe()
    .disposed(by: disposeBag)

subject.onNext(2)

subject.onCompleted()

subject.onNext(3)

subject.debug("🔴")
    .subscribe()
    .disposed(by: disposeBag)
profile
🧑🏻‍💻 iOS Developer @TOSS

1개의 댓글

comment-user-thumbnail
2022년 4월 15일

comleted라고 오타가 난거 같아요;;
덧: 잘 보고 있습니다. 감사합니다.

답글 달기