征服ReactiveSwift:基本体(第2部分)

征服ReactiveSwift系列的第一部分中,我们分析了命令式方法与功能性反应式方法之间的区别。 在本文中,我们将从ReactiveSwift的各种基元(基本构建块)开始,深入研究ReactiveSwift的领域。

ReactiveSwift的作者将其描述如下:

ReactiveSwift提供了可组合的,声明性的和灵活的原语,这些原语是围绕随着时间流逝的价值流这一宏伟概念而构建的。

ReactiveSwift带有许多强大的原语,使您能够以功能性的反应方式编写代码。 学习这些原语的最简单方法是根据它们的角色将它们分为不同的类别。 请参考下图。

正如我们在上一篇文章中讨论的那样,在反应式编程中,我们针对随时间的一系列变化而不是针对特定时间点的状态对系统进行建模。 “ ”类别下的原语负责这些更改的生成和传播。 在该类别下,我们有以下基元: Event,Signal,Signal Producer,Action

1.活动

事件表示发生了某些事情。 它是流的基本传输单位。 事件有四种类型:

  • 值:具有有效信息的事件
  • 失败:表示错误的事件
  • 已完成:表示流结束的事件。 此事件后将不再发出其他事件。
  • 中断:表示事件产生被中断。

2.信号

信号是事件的单向流。 可以通过观察员订阅来访问信号的每个事件。 观察信号不会给信号带来任何副作用。 所有事件立即发送给给定信号的所有观察者。

3.信号产生器

顾名思义, SignalProducer是产生信号的东西。 它封装了可以在以后开始的工作(也可以重复)。 换句话说, SignalProducer生产者封装了延迟且可重复的工作。 启动它时,将创建一个新信号,该信号将发出信号,作为调用封装工作的结果。 因此,由于需要启动SignalProducer ,因此据说它很冷,而Signal是温暖的。

4.行动

在延迟和可重复的工作中也使用了动作 。 它封装了SignalProducer的工作。 我们要更好地控制动作而不是信号产生器 。 例如,我们可以通过发送不同的输入值来控制输出。 可以启用或禁用它。 可以通过属性 (如下所述)来被动地控制其状态。 当用输入调用时, 动作将输入和最新状态应用于预定义的工作,并将输出推送给观察者。

5.财产

属性是一个可观察的框,它存储一个值并通知观察者该值的将来更改。 它具有用于生产者和信号的吸气剂,可发出可以观察到的值。 可以使用初始值和SignalSignalProducer或直接通过另一个Property初始化Property

下图说明了各种基元如何相互关联。

此类别下的原语侦听源组件发出的事件并对其起作用。 在该类别下,我们有以下基元: Observer,MutableProperty。

1.观察者

观察者封装了响应所发出事件而要执行的工作。 它是一个简单的包装器,用于将事件作为输入的闭包。

2. MutableProperty

MutableProperty是一个可观察的盒子,它像Property一样存储值。 它还具有用于生产者和信号的吸气剂,这些吸气剂发出可以观察到的值。 但是,与属性不同可以直接对其进行突变。 它符合BindingTargetProvider协议,因此它可以使用SignalSignalProducerProperty通过<〜 (绑定运算符)接收的值来更新其值。

运营商指定消费者消费来源的方式。 ReactiveSwift带有一组丰富的运算符,用于执行副作用,变换,合并,展平等。这些将在后续文章中进行讨论。

此类别下的基元决定了源和消费者之间交互的生命周期。 我们在此类别下有一次性终身使用

1.一次性

一次性是用于内存管理和取消的机制。 观察信号返回一次性用品。 处置一次性用品可防止观察者从该信号接收任何将来的事件。 但是,这不会影响信号。 在启动SignalProducer时 ,我们得到了一个一次性工具,可用于取消已开始的工作。

2.终身

生存期表示对象的生存期。 当观察结果可能超出观察者时,此原语很有用。 例如,只要屏幕上有UI组件,我们就希望观察到一条通知。

现在,让我们了解如何使用这些原语来完成我们的工作。 让我们举个例子。

文本字段的字符数大于10时启用按钮。

步骤1:定义讯号

 让信号= textField.reactive.continuousTextValues 

在此,在文本textfield键入的文本通过信号textField.reactive.continuousTextValues表示。 是ReactiveCocoa的一部分,而不是ReactiveSwift的一部分。 ReactiveCocoa用声明式ReactiveSwift原语包装Cocoa框架的各个方面。

步骤2:转换信号

第一步中创建的信号会发出可选字符串。 我们必须将其转换为通过操作符map发出布尔值。

 让transformSignal =信号 
.map {文字为
文字?? “”}
.map {文字为
text.characters.count> 10
}

第三步:观察信号

接下来,我们将观察信号并执行操作,即设置按钮的isEnabled 。 在这里,我们创建一个类型的信号,这意味着它可以消耗类型的信号/信号生成器。 然后我们通过observe原语开始观察信号。

 让观察者= Signal  .Observer(value:{value in 
button.isEnabled =值
})
让一次性= transformedSignal.observe( 观察者

步骤4:停止观察信号

observe原语返回一个Disposable实例,该实例可用于停止观察信号。

 一次性的?.dispose() 

最好的做法是将所有观察者都放置在类的deinit中。

整个东西……。

  //定义消费者,让观察者= Signal  .Observer(value:{value in 
button.isEnabled =值
})
//定义源 let signal = textField.reactive.continuousTextValues
让transformSignal =信号
.map {文字为
文字?? “”}
.map {文字为
text.characters.count> 10
}
//消耗信号让一次性= transformedSignal.observe(observer) //限制范围
一次性的?.dispose()

您可以在以下文章中获得更多有关反应组件的见解:

活性可可/活性迅速

ReactiveSwift –随时间流逝的价值

github.com

在本文中,我们介绍了ReactiveSwift的不同组件,以及如何使用它们以功能性的反应方式编写代码。 您可以在此处找到示例代码。 在下一篇文章中,我们将讨论如何创建和观察信号。

谢谢您阅读😄。


这是本系列文章的完整列表。

  1. 征服ReactiveSwift:信号和观察者(第3部分)
  2. 征服ReactiveSwift:SignalProducer(第4部分)
  3. 征服ReactiveSwift:属性(第5部分)
  4. 征服ReactiveSwift:动作(第6部分)