征服ReactiveSwift:SignalProducer(第4部分)

欢迎来到我的征服ReactiveSwift系列文章的第4部分。 在上一篇文章中,我们学习了如何创建和观察信号。 在本文中,我们将介绍SignalProducer的概念它是Source类别下的重要原语。

定义

顾名思义, SignalProducer是产生Signal的东西。 基本上, SignalProducer封装了延迟且可重复的工作,这些工作在启动时会生成Signal

好吧,它有什么用?

请记住,在上一篇文章中,我们研究了以下问题陈述。

每隔五秒钟打印一次已过时间的消息。

我们创建了一个信号,该信号在接下来的50秒内每5秒发出一个整数。 然后,我们观察这些整数并打印经过的时间。 让我们假设,现在我们希望这从按钮轻按开始。 但是,作为观察者,我们只能观察信号,而不能使其开始或停止。 对于这种情况, SignalProducer非常适合。

因此,让我们开始吧!

我们将把整数发射代码封装在SignalProducer中。

  //创建SignalProducer 
 让signalProducer:SignalProducer  = 
SignalProducer {(观察者,生命周期)在
 对于i in 0 .. <10 { 
DispatchQueue.main.asyncAfter(截止日期:.now()+ 5.0 * Double(i)){
viewer.send(值:i)
如果i == 9 {//标记第9次迭代完成
reader.sendCompleted()
}
}
}
}

在这里, SignalProducer用一个闭包初始化,该闭包在调用SignalProducer的 start方法时执行。 此闭包接受类型为Signal.Observer观察者以及类型为Lifetime生存期。 观察者用于发送值。 如果停止观察,则一生将为我们提供取消正在进行的工作的机会。

现在我们准备好了一个SignalProducer 。 让我们开始观察它。

  //创建观察者 
 让signalObserver = Signal  .Observer( 
值:{
print(“经过的时间= \(值)”)
},已完成:{
打印(“完成”)
},中断了:{
打印(“中断”)
})
  //启动SignalProducer 
  signalProducer.start(signalObserver) 

在这里我们必须记住, SignalProducer的每次调用都会产生不同的信号。 观察者对SignalProducer的不同调用收到的事件的顺序和值也不同。

假设我们想在10秒后中断SignalProducer。 为此,我们必须在10秒后处理掉它。

  //启动SignalProducer 
 让一次性= signalProducer.start(signalObserver) 
  // 10秒后处理 
DispatchQueue.main.asyncAfter(最后期限:.now()+ 10.0){
possible.dispose()
}

根据我们当前的实现,即使在10秒钟后放置观察者SignalProducer也会继续发射整数50秒钟。 构造SignalProducer时,释放资源并在中断时停止正在进行的任务很重要。 因此,让我们修复该问题。

 让signalProducer:SignalProducer  = 
SignalProducer {(观察者,生命周期)在
对于i in 0 .. <10 {
DispatchQueue.main.asyncAfter(截止日期:.now()+ 5.0 * Double(i)){
警卫!lifetime.hasEnded else {
reader.sendInterrupted()
返回
}
viewer.send(值:i)
如果i == 9 {
reader.sendCompleted()
}
}
}
}

我们将检查生命周期的 hasEnded属性,并将中断事件发送为sendInterrupted

信号vs信号产生器

要了解SignalSignalProducer之间的区别,让我们以电视和点播流服务为例。 信号的行为就像电视馈送,它是连续的视频和音频流。 在给定的时间点,每个TV Feed的观看者都可以看到相同的帧序列。 观察者既不能对电视Feed产生任何副作用,也不能启动或停止Feed。 观察者只能开始和停止接收提要。 另一方面, SignalProducer就像YouTube等点播流服务一样。 在这里,观察者可以接收视频和音频流,但是对于不同的观察者,该流的顺序是不同的。 在这里观察者可以开始和停止提要。

因此, 信号通常用于表示已经“进行中”的事件流,例如通知,用户输入等。另一方面, SignalProducers用于表示需要启动的操作或任务。 例如,像网络请求一样,每次start调用都会创建一个新的基础操作。 对于Signal ,结果可能在附加任何观察者之前发送。 对于SignalProducer而言 ,除非启动结果,否则不会发送结果。

结论

我希望本文能使您对何时使用Signal和何时使用SignalProducer有所了解,并更好地理解两者之间的关系。 您可以在这里找到本文的示例代码。 在下一篇文章中,我们将讨论如何限制观察范围。

谢谢您阅读🙂