zwvista

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

Combine学习笔记

作者:@zwvista
本文为作者原创,转载请注明出处:https://www.cnblogs.com/zwvista/p/16574993.html


目录

Combine
Publisher Operator Subscriber
Subject
Subscriber Cancellable
AnyPublisher AnyCancellable
@Published

Combine

Combine是一个函数响应式编程库。

Publisher Operator Subscriber

Publisher(发布者)生成并发布数据。Publisher 是一个协议。

  • 发布者可以发布0个1个或多个数据,然后正常结束或出错。
  • 发布者的类型由所发布的数据(output,输出)的类型和所发生的错误(failure,失败)的类型构成。
    <Output Type, Failure Type>

Operator(操作符)响应和更改数据。

  • 操作符的输入类型由所接收的数据(input,输入)的类型和所接收的错误(failure,失败)的类型构成。
  • 操作符的输出类型由所生成的数据(output,输出)的类型和所发生的错误(failure,失败)的类型构成。
    <Input Type, Failure Type> to <Output Type, Failure Type>

Subscriber(订阅者)订阅数据。Subscriber 是一个协议。

  • 订阅者的类型由所接收的数据(input,输入)的类型和所接收的错误(failure,失败)的类型构成。
    <Input Type, Failure Type>
// Publisher
Just(5)
// Operator
.map { value -> String in
return "a string"
}
// Subscriber
.sink { receivedValue in
print("The end result was \(receivedValue)")
}

Subject

Subject 是指遵循 Subject 协议的特殊发布者。Subject 协议继承自 Publisher 协议。
Subject 通过该协议中的 .send(_:) 方法来发布数据。
常用 Subject 有 CurrentValueSubject 和 PassthroughSubject。

  • PassthroughSubject 没有初值,没有当前状态(值),订阅者无法接收订阅之前发布的数据。
    PassthroughSubject 是门铃,没有开关状态,只有在家才能接收其信息。
  • CurrentValueSubject 有初值,有当前状态(值),订阅者可以接收订阅之前最后发布的数据。
    CurrentValueSubject 是电灯,有开关状态,回家即可观察其状态。

PassthroughSubject vs. CurrentValueSubject explained

let relay = PassthroughSubject<String, Never>()
let subscription = relay.sink { value in
print("subscription1 received value: \(value)")
}
relay.send("Hello")
relay.send("World!")
/*
subscription1 received value: Hello
subscription1 received value: World!
*/
let variable = CurrentValueSubject<String, Never>("")
variable.send("Initial text")
let subscription2 = variable.sink { value in
print("subscription2 received value: \(value)")
}
variable.send("More text")
/*
subscription2 received value: Initial text
subscription2 received value: More text
*/

Subscriber Cancellable

Is there an alternative to Combine's @Published that signals a value change after it has taken place instead of before?

常用订阅者有 sink 和 assign。
sink 使用回调函数来处理结果值。
assign 使用结果值来设置其他值。
assign(to:on:) 将结果值赋予其他某个对象的某个属性。
assign(to:) 将结果值赋予其他某个Publisher。

Cancellable (可取消)是一个协议。
sink 和 assign(to:on:) 返回 Cancellable 的实例。
通过调用 Cancellable 协议的 cancel 方法可以取消订阅。

let cancellable = publishingSource.sink { someValue in
print(".sink() received \(someValue)")
}
// cancellable.cancel()
let cancellable = publishingSource
.receive(on: RunLoop.main)
.assign(to: \.isEnabled, on: yourButton)
// cancellable.cancel()
publishingSource.assign(to: &publishingSource2)

AnyPublisher AnyCancellable

AnyPublisher 为遵循 Publisher 协议的具体类。
通过调用 Publisher 协议的 eraseToAnyPublisher 方法可以将任何 Publisher 对象转化为 AnyPublisher 对象,方便统一处理并隐藏真实类型。
AnyCancellable 为遵循 Cancellable 协议的具体类。
sink 和 assign(to:on:) 返回 AnyCancellable 的实例。
AnyCancellable 的实例必须保存在该类型的变量或容器中。否则该实例会被回收并导致订阅被取消。

let pub: AnyPublisher<String, Never> = ["Here","we","go!"].publisher
.eraseToAnyPublisher()
var subscriptions = Set<AnyCancellable>()
pub.sink { receivedValue in
print("received value: \(receivedValue)")
}.store(in: &subscriptions)
/*
received value: Here
received value: we
received value: go!
*/

@Published

@Published 是一种提供 Publisher 的属性包装器(Property Wrapper)。
如果 v 是一个 Value 类型的属性,并且 v 属性使用 @Published 修饰,
那么 $v 就是一个 Published<Value>.Publisher 类型的 Publisher。

class Weather {
@Published var temperature: Double
init(temperature: Double) {
self.temperature = temperature
}
}
// temperature 的类型为 Double
// $temperature 的类型为 Published<Double>.Publisher
let weather = Weather(temperature: 20)
let cancellable = weather.$temperature.sink() {
print ("Temperature now: \($0)")
}
weather.temperature = 25
// Temperature now: 20.0
// Temperature now: 25.0

posted on   zwvista  阅读(73)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示