「Combineをはじめよう」を読んだ

nextpublishing.jp

第2章 SubscribeとSubscription

import Combine

let subject = PassthroughSubject<String, Never>()

final class Receiver {
    let subscription: AnyCancellable

    init () {
        subscription = subject
            .sink { value in
                print("received:", value)
            }
    }
}

let receiver = Receiver()
subject.send("a")  // "received: a"
subject.send("b")  // "received: b"

sink メソッドには戻り値があり、それを保持しないと受信処理が行われない。

ここが頭に入ってこなかった。というのも、そういものだと受け入れればいいことなのかもしれないが、もう少し深く見て理解したい。

sink(receiveValue:)の戻り値を破棄せずに保持しておく必要がある理由を探す - カルボナーラ街道

第3章 Publisher

import Combine

let subject = PassthroughSubject<String, Never>()

let publisher = subject.eraseToAnyPublisher()

final class Receiver {
    var subscriptions = Set<AnyCancellable>()
    
    init() {
        publisher
            .sink { value in
                print("received:", value)
            }
            .store(in: &subscriptions)
    }
}

let receiver = Receiver()
subject.send("a")  // "received: a"
subject.send("x")  // "received: x"

Subjectをどこかに渡す時はeraseToAnyPublisher()を使ってPassthroughSubjectからAnyPublisherに型を変更して、ただのPublisherとして渡す。
そうすることでSubject特有のsendを外部から実行できないようにする。

第4章 Operator

4.1 バインディング

import Combine

final class Model {
    @Published var value: String = "0"
}

let model = Model()

final class ViewModel {
    var text: String = "" {
        didSet {
            print("didSet text:", text)
        }
    }
}

final class Receiver {
    var subscriptions = Set<AnyCancellable>()
    let viewModel = ViewModel()
    
    init() {
        model.$value
            .assign(to: \.text, on: viewModel)
            .store(in: &subscriptions)
    }
}

let receiver = Receiver()
model.value = "1"
model.value = "2"
model.value = "3"

おさらいだが、model.$value に対して .store(in:) を指定する必要がある。
これにより model.$valueサブスクリプションストリームが即時で破棄されない。

第5章 Combineのコンセプト

5.2 リアクティブプログラミングとは

それら(非同期イベント)を扱う仕組みは既に存在しています。FoundationやUIKitでは、Delegate、~

Delegateはたしかに宣言的な記述で非同期イベントの処理を行っている。言われてみれば確かにそうだと思った。

感想

  • 過去にCombineを試したことはあっても、中々理解できてなかった。今回で触りの部分は結構理解できた実感があって読んでよかった
  • 著者の方も言っていたが、Publisherの説明としてSubjectを用いることでsendを開発者側でハンドリングできるため、理解しやすかった

参考