gpt4 book ai didi

swift - 观察事件传递到 reactiveswift

转载 作者:搜寻专家 更新时间:2023-10-31 08:05:35 25 4
gpt4 key购买 nike

我已多次阅读文档并需要澄清...

给定以下代码段:

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 应该在之后 dealloc

问题:

x 将接收哪些事件(按顺序):

  • 值(value)和完成度?是否保证在处理值事件时 self 仍然存活?

  • 仅完成?我怀疑是这种情况,但如果是这样,请引用一些文档。因为完成事件不会立即传播。

xy 使用不同的 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 运算符不会发送单值事件,然后以某种方式“安排”完成事件的传递以供稍后使用。值事件和完成事件的传递都发生在上游信号传递值事件的过程中,观察者及其引用的释放发生在 signal 完成传递其第一个事件之前。

当您说“完成事件不会立即传播”时,我假设您是在谈论 APIContracts file 的部分这讨论了如何立即传播故障和中断。这只是注意到许多运算符会立即传递这些事件,即使它们是异步或时移运算符也是如此。

take 运算符不是时移或异步运算符。在这种情况下,运算符(operator)不会传播来自上游信号的完成事件;相反,它正在生成完成事件本身,并且it is doing so synchronously immediately after it propagates the value event .

我是在介绍一场比赛吗?

你是对的,ReactiveSwift 本身并没有引入异步或并发,所以这里不存在传统意义上的“竞争”。但是,我相信 Signal 的 API 契约并不能保证事件按照观察者开始观察的顺序传递给观察者。所以这段代码的行为在技术上是未定义的,可能会在 ReactiveSwift 的 future 版本中发生变化。

对 x 和 y 使用不同的调度程序是否会对结果产生影响?

现在这实际上会引入一个竞争,因为 take 的完成事件将在您为该观察者设置的任何调度程序上传递,并且该事件的传递将触发 deinit 属于 self

关于swift - 观察事件传递到 reactiveswift,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56179200/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com