观察事件传递到 reactiveswift
Observation event passing in reactiveswift
我已多次阅读文档并需要说明...
鉴于以下代码段:
let signal: Signal<Value,Error>
//call this observer y
signal.take(first: 1).observeValues{ (value) in
//intended strong capture on self. this is the only one that retains self so if this observer is triggered and completes, self should dealloc
self.doSomethingElse(value) //trivial call, no async or thread hopping
}
//call this observer x
signal.take(duringLifetimeOf: self).observeValues{ [unowned self] (value) in //is this safe or better to use weak and guard against it?
self.doSomeProcess(value) //trivial call, no async or thread hopping
}
如果 signal
被触发并通知其观察者 value event
:
1) 观察者 y
将在 x
之前收到通知(假设是因为它在队列中较早被观察到)
2) 由于 y
会在处理值后完成,self
应该在之后释放
问题:
x
将接收哪些事件(按顺序):
值和完成度?是否保证在处理 value 事件时 self 仍然活着?
仅完成?我怀疑是这种情况,但如果是这样,请参考一些文档。因为完成事件不会立即传播。
对 x
和 y
使用不同的 Scheduler
会对结果产生影响吗?
最后,我是在介绍race
吗?我对此表示怀疑,因为除非开发人员明确说明,否则 reactiveSwift 不会引入并发。
我整理了一个小示例控制台应用程序来测试它。正如我在评论中所说,take(first: 1)
在传递 1 值事件后立即同步传递完成事件,这意味着 y
对 self
的引用将在传递任何值之前消失x
。假设这是对 self
的唯一强引用,x
将不会收到任何值。
import Foundation
import ReactiveSwift
import ReactiveCocoa
class MyClass {
init(signal: Signal<String, Never>) {
//call this observer y
signal.take(first: 1).observeValues{ (value) in
//intended strong capture on self. this is the only one that retains self so if this observer is triggered and completes, self should dealloc
self.doSomethingElse(value) //trivial call, no async or thread hopping
}
//call this observer x
signal.take(duringLifetimeOf: self).observeValues{ [unowned self] (value) in //is this safe or better to use weak and guard against it?
self.doSomeProcess(value) //trivial call, no async or thread hopping
}
}
func doSomethingElse(_ value: String) {
print("Something Else: \(value)")
}
func doSomeProcess(_ value: String) {
print("Some Process: \(value)")
}
}
let (signal, input) = Signal<String, Never>.pipe()
_ = MyClass(signal: signal)
input.send(value: "1")
input.send(value: "2")
果然,doSomeProcess
从未被调用过:
Something Else: 1
Program ended with exit code: 0
关于 ReactiveSwift
要记住的关键一点是,一切都是同步发生的,除非您使用一组特定的运算符或您自己的代码明确指定其他方式。因此 take
运算符不会发送一个值事件,然后以某种方式 "schedule" 发送完成事件供以后使用。值事件和完成事件的传递都发生在上游信号传递值事件期间,观察者及其引用的释放发生在 signal
完成其第一个事件传递之前。
当您说 "completion events aren't propagated immediately" 时,我假设您是在谈论 APIContracts
file 中关于如何立即传播故障和中断的部分。这只是注意到许多运算符会立即传递这些事件,即使它们是异步的或 time-shifting 个运算符。
take
运算符不是 time-shifting 或异步运算符。在这种情况下,操作员不会传播来自上游信号的完成事件;相反,它是 生成 完成事件本身,并且 it is doing so synchronously immediately after it propagates the value event.
我是在介绍比赛吗?
你是对的,ReactiveSwift
本身并没有引入异步或并发,所以这里没有传统意义上的"race"。但是,我相信 Signal
的 API 合同并不能保证事件按照观察者开始观察的顺序传递给观察者。所以这段代码的行为在技术上是未定义的,可能会在 ReactiveSwift
的未来版本中发生变化。
对 x 和 y 使用不同的调度程序会对结果产生影响吗?
现在这实际上会引入一场竞赛,因为 take
的完成事件将在您为该观察者设置的任何调度程序上传递,并且该事件的传递将触发 deinit
的 self
.
我已多次阅读文档并需要说明...
鉴于以下代码段:
let signal: Signal<Value,Error>
//call this observer y
signal.take(first: 1).observeValues{ (value) in
//intended strong capture on self. this is the only one that retains self so if this observer is triggered and completes, self should dealloc
self.doSomethingElse(value) //trivial call, no async or thread hopping
}
//call this observer x
signal.take(duringLifetimeOf: self).observeValues{ [unowned self] (value) in //is this safe or better to use weak and guard against it?
self.doSomeProcess(value) //trivial call, no async or thread hopping
}
如果 signal
被触发并通知其观察者 value event
:
1) 观察者 y
将在 x
之前收到通知(假设是因为它在队列中较早被观察到)
2) 由于 y
会在处理值后完成,self
应该在之后释放
问题:
x
将接收哪些事件(按顺序):
值和完成度?是否保证在处理 value 事件时 self 仍然活着?
仅完成?我怀疑是这种情况,但如果是这样,请参考一些文档。因为完成事件不会立即传播。
对 x
和 y
使用不同的 Scheduler
会对结果产生影响吗?
最后,我是在介绍race
吗?我对此表示怀疑,因为除非开发人员明确说明,否则 reactiveSwift 不会引入并发。
我整理了一个小示例控制台应用程序来测试它。正如我在评论中所说,take(first: 1)
在传递 1 值事件后立即同步传递完成事件,这意味着 y
对 self
的引用将在传递任何值之前消失x
。假设这是对 self
的唯一强引用,x
将不会收到任何值。
import Foundation
import ReactiveSwift
import ReactiveCocoa
class MyClass {
init(signal: Signal<String, Never>) {
//call this observer y
signal.take(first: 1).observeValues{ (value) in
//intended strong capture on self. this is the only one that retains self so if this observer is triggered and completes, self should dealloc
self.doSomethingElse(value) //trivial call, no async or thread hopping
}
//call this observer x
signal.take(duringLifetimeOf: self).observeValues{ [unowned self] (value) in //is this safe or better to use weak and guard against it?
self.doSomeProcess(value) //trivial call, no async or thread hopping
}
}
func doSomethingElse(_ value: String) {
print("Something Else: \(value)")
}
func doSomeProcess(_ value: String) {
print("Some Process: \(value)")
}
}
let (signal, input) = Signal<String, Never>.pipe()
_ = MyClass(signal: signal)
input.send(value: "1")
input.send(value: "2")
果然,doSomeProcess
从未被调用过:
Something Else: 1
Program ended with exit code: 0
关于 ReactiveSwift
要记住的关键一点是,一切都是同步发生的,除非您使用一组特定的运算符或您自己的代码明确指定其他方式。因此 take
运算符不会发送一个值事件,然后以某种方式 "schedule" 发送完成事件供以后使用。值事件和完成事件的传递都发生在上游信号传递值事件期间,观察者及其引用的释放发生在 signal
完成其第一个事件传递之前。
当您说 "completion events aren't propagated immediately" 时,我假设您是在谈论 APIContracts
file 中关于如何立即传播故障和中断的部分。这只是注意到许多运算符会立即传递这些事件,即使它们是异步的或 time-shifting 个运算符。
take
运算符不是 time-shifting 或异步运算符。在这种情况下,操作员不会传播来自上游信号的完成事件;相反,它是 生成 完成事件本身,并且 it is doing so synchronously immediately after it propagates the value event.
我是在介绍比赛吗?
你是对的,ReactiveSwift
本身并没有引入异步或并发,所以这里没有传统意义上的"race"。但是,我相信 Signal
的 API 合同并不能保证事件按照观察者开始观察的顺序传递给观察者。所以这段代码的行为在技术上是未定义的,可能会在 ReactiveSwift
的未来版本中发生变化。
对 x 和 y 使用不同的调度程序会对结果产生影响吗?
现在这实际上会引入一场竞赛,因为 take
的完成事件将在您为该观察者设置的任何调度程序上传递,并且该事件的传递将触发 deinit
的 self
.