Combine简介
Combine是一个苹果用来处理事件的新的响应式框架,支持iOS 13及以上版本。
你可以使用Combine去统一和简化在处理类似于target-action,delegate,kvo等事情的代码。
iOS目前已经有第三方的响应式框架了,如:RxSwift、ReactiveCocoa,但是苹果现在发布了自己的新的框架。
它提供了一种声明式、函数式的编程方式,可以让开发者更加简单、高效地处理异步数据流。
Combine核心概念
Combine的核心概念是Publisher、Subscriber和Operator。发布者,订阅者和中间操作者。
发布者Publisher:可以将值或错误发送给订阅者,并且在完成或取消时,向订阅者发送相应的消息。
订阅者Subscriber:接收发布者发送的值、错误和完成信息,并进行相应的处理。
操作符Operator:用来对数据流进行转换、过滤、合并等处理,Combine框架中提供了很多操作符,例如map、filter、merge等。
当一个Publisher发布一个事件时,Subscriber会被通知这个事件,并执行相应的操作。
一个Subscriber可以订阅多个Publisher,并且每个Publisher都可以同时拥有多个Subscriber。当所有的Subscriber都取消订阅时,Publisher会停止发布事件。
Operator可以对事件流进行各种操作,包括数据转换、过滤、组合等。比如,map操作可以将一个事件流中的元素转换成另一个类型,filter操作可以过滤出符合条件的元素,merge操作可以将多个事件流合并成一个事件流等。
map操作符可以将数据流中的值进行转换,返回一个新的数据流。例如,将一个字符串转换成大写形式:
let stringPublisher = Just("hello, world!") let uppercasedPublisher = stringPublisher.map { $0.uppercased() }filter对数据流中的值进行过滤,返回一个新的数据流。例如,过滤掉数组中的偶数:
let arrayPublisher = [1, 2, 3, 4, 5].publisher let oddPublisher = arrayPublisher.filter { $0 % 2 != 0 }merge对数据流进行合并,生成一个数据流。例如,将两个发布者合并成一个:
let publisher1 = Just("hello") let publisher2 = Just("world") let mergedPublisher = Publishers.Merge(publisher1, publisher2)下面是一个简单的例子,展示了如何使用Combine来监听一个UITextField的文本输入
import UIKit import Combine class ViewController: UIViewController { @IBOutlet weak var textField: UITextField! var cancellables = Set<AnyCancellable>() override func viewDidLoad() { super.viewDidLoad() // 创建一个订阅者,打印出文本输入的内容 let subscriber = Subscribers.Assign(object: self.textField, keyPath: \.text) // 订阅文本输入框的文本变化事件 self.textField.textPublisher(for: .editingChanged) .map { $0.text ?? "" } .subscribe(subscriber) .store(in: &cancellables) } } extension UITextField { func textPublisher() -> AnyPublisher<String, Never> { NotificationCenter.default .publisher(for: UITextField.textDidChangeNotification, object: self) .map {($0.object as? UITextField)?.text ?? ""} .eraseToAnyPublisher() } }
AnyCancellable Combine 中还定义了一个 AnyCancellable 类,实现了 Cancellable 协议,特点是会在该类析构时自动执行 cancel 方法。
在实际开发中,当 Subscriber 在某个时候不想接收 Publisher 发布的数据时,可以取消订阅以释放资源。 Combine 中提供了 Cancellable 协议,该协议中定义了一个 cancel 方法,用于取消订阅流程。
import Combine let subject = PassthroughSubject<String, Never>() // 创建PassthroughSubject // 订阅 let subscription = subject.sink(receiveCompletion: { _ in print("receiveCompletion") }, receiveValue: { value in print(value) }) // 发送数据 subject.send("hello") // 中途取消订阅 subscription.cancel() // 后面发送的数据都会失败 subject.send("world") subject.send(completion: .finished) /* 输出: hello */可以理解为 AnyCancellable是一种管理订阅状态的工具,能根据开发者需要在某个时段切断 Publisher和 Subscriber的联系。 AnyCancellable 的一个应用就是可以在某种情况下中断网络请求,实现如下:
import UIKit import Combine let dataPublisher = URLSession.shared.dataTaskPublisher(for: URL(string: "https://louyu.cc")!) let cancellableSink = dataPublisher.sink { completion in switch completion { case .finished: break case .failure(let error): print("error: \(error)") break } } receiveValue: { value in print("received \(value)") } cancellableSink.cancel() //取消网络请求
参考文章地址: https://www.jianshu.com/p/1dc27229a533 https://louyu.cc/articles/ios-swift/2021/03/?p=2865/ 标签:Publisher,订阅,Subscriber,let,数据流,Combine,Swift From: https://www.cnblogs.com/zhou--fei/p/17720908.html