Combine之简述
用Apple的话说,Combine是:
a declarative Swift API for processing values over time
这句话包含了Combine的3大核心:
-
declarative
表示Combine的语法是声明式的 -
values
表示Combine处理的数据不是单独的,是多个且复杂的 -
over time
表示要处理的数据带有时间影响,也就是带有时间序列的事件流
总结一下,Combine就是专门用于处理事件流的声明式编程框架。
这里需要解释下为何是事件流而不是数据流,比如有这样一个场景:
- 当用户输入一个关键词
- 去重
- 发送网络请求
- 错误校验
- 数据解析
上边就是所谓的5个事件,每个事件都有各自的输入和输出。如果我们把他们链接在一起,就组成了一条数据流通管道,简称数据流。我们看下代码是怎样的?
enum NetworkError: Error {
case invalidResponse
}
struct Student: Codable {
let name: String
let age: Int
}
let publisher = PassthroughSubject<String, Never>()
cancellable = publisher
.removeDuplicates()
.flatMap { value in
return URLSession.shared.dataTaskPublisher(for: URL(string: "https://xxx.com?name=\(value)")!)
}
.tryMap { (data, response) -> Data in
guard let httpResp = response as? HTTPURLResponse, httpResp.statusCode == 200 else {
throw NetworkError.invalidResponse
}
return data
}
.decode(type: Student.self, decoder: JSONDecoder())
.catch { _ in
Just(Student(name: "", age: 0))
}
.sink(receiveCompletion: {
print($0)
}, receiveValue: {
print($0)
})
publisher.send("张三")
复制代码
什么是Functional reactive programming(函数响应式编程)
image.png网络上已经有很多文章详细地介绍了函数响应式编程,但读下来还是令人产生很多疑惑,在本小节,我尝试对函数响应式编程做一些简单的介绍。
就像上图所示一样,要理解函数响应式编程就需要分别理解函数式编程和响应式编程。
函数式编程非常好理解,我们从下边2个重要概念入手:
- 予以函数数学特性
- 予以函数一等公民身份
那么什么叫予以函数数学特性呢?很简单,凡是带有数学特性的东西都必须是逻辑严谨的,计算安全的。在函数式编程的世界中,函数绝对不能修改变量的状态,一个输入数据必定产生一个固定的输出数据。
image.png当一个函数是安全的时候,它就可以参与到数据的运算和传递。因此,函数身份提升到一等公民,它既可以作为另一个函数的参数,也可以作为另一个函数的返回值。
可以在这里了解到Swift函数式编程的详细内容:一文读懂Swift函数式编程
来到响应式编程就没那么好理解了,很多开发的同学习惯了写函数,不一定习惯编写响应式的代码。所谓的响应实质上就暗含了Stream的概念。
这时候,输入数据就不再是死数据,而是随着时间而不断变化,不同的输入会产生不同的输出,因此,我们就需要对这些输出做出一定的响应。
举个例子:
var a = 1
var b = 2
c = a + b
/// c == 3
a = 2
复制代码
在上边的代码中,我们把a和b想象成输入数据,把c想象成输出数据,当我改变了a的值后,输出数据c并没有改变,这就不是响应式的。
响应式编程思想解决的问题就是数据的流动问题,尤其当数据是异步流动的情况,更复杂一点是多个数据的异步流动。
当我们把函数式编程和响应式编程组合起来就是函数响应式编程。像下边这张图一样:
image.png把数据的处理过程想象成由多个函数组成的黑盒子,
image.png也可以想象成水流管道,我们只需要提前布置好合适的管道,就等待数据输入,然后做出响应。
image.png什么时候用Combine?
SwiftUI中Views刷新机制的核心是Source of Truth
,即Views展示的内容完全依赖其状态,状态改变,UI也跟着改变。虽然SwiftUI和Combine是天然的同盟关系,在其他的框架中,仍然可以使用Combine。
如果以最宏观的视角看问题,当遇到下边2个问题时,就可以考虑使用Combine:
- 异步任务
- 数据会随时间而改变
在平时的开发中,异步任务非常之多,Combine天然就是处理异步任务的好手,在后边的文章中会有这方面详细的讲解。
总结
Combine是iOS13引进的,因此要想使用Combine开发程序,系统版本最低要求为iOS13。UIKit和SwiftUI都可以使用。尤其是SwiftUI,有了Combine这一利器之后,真正的做到了逻辑和UI分离。
网友评论