🐾
[AnyCancellable]は関数内に置かない方が良いという話
[AnyCancellable]関数内に配置すると...
当たり前ですが、関数を抜ける時に解放されてしまうので購読が終了してしまいます。
従って下記のコードでは、sink内で値を拾うことができません。
[AnyCancellable]は解放されないところにおきましょう
class Subscriber {
private func publisher() -> AnyPublisher<String, Never> {
return Future { promise in
promise(.success("AAA"))
}
.delay(for: .seconds(1), scheduler: RunLoop.main)
.eraseToAnyPublisher()
}
func subscribe() {
print("start subscribe")
var cancellables: [AnyCancellable] = []
publisher()
.sink { print("receive value: \($0)") }
.store(in: &cancellables)
}
}
let subscriber = Subscriber()
subscriber.subscribe()
関数内に配置しても値を拾えるパターンがある
実は関数内に配置しても値を拾えるパターンがありました。
同期的なタイミングで値を流す場合です。
class Subscriber {
// .delayを消した
private func publisher() -> AnyPublisher<String, Never> {
return Future { promise in
promise(.success("AAA"))
}
.eraseToAnyPublisher()
}
func subscribe() {
print("start subscribe")
var cancellables: [AnyCancellable] = []
publisher()
.sink { print("receive value: \($0)") }
.store(in: &cancellables)
}
}
let subscriber = Subscriber()
subscriber.subscribe()
最後に
まず、もともと書かれていたコードの制約で、関数内しか[AnyCancellable]を
配置できませんでした。protocolをextensionする形で実装されていたためです。
API通信をモックで実装していた時は、関数内に[AnyCancellable]を配置してもsinkが実行されていたので、この挙動に気づきませんでした。
関数内に置くことはあんまりないけど、動くしまぁ大丈夫かーくらいで実装を進めてました笑
モックは非同期で値を返すようにしておいたほうが良いですね。
最後まで読んでいただき、ありがとうございました。

株式会社 カラビナテクノロジーは「命綱や支点を素早く確実に繋ぐカラビナ。そんなカラビナのような役割をテクノロジーで実現したい」という想いのもと、福岡で設立。 主にシステム開発・アプリ開発・ Webサイト制作を行っています。採用情報→karabiner.tech/career
Discussion