为什么从 SwiftUI 视图初始值设定项调用时我的发布者订阅会立即取消?
我创建了一个 gravityPublisher
(用于接收当前重力矢量的更新)并通过调用以下函数来订阅它:
private func enableGravityDetection(_ gravityEnabled: Bool) {
if gravityEnabled {
if cancellable == nil {
cancellable = gravityProvider
.gravityPublisher
.receive(on: RunLoop.main)
.print()
.assign(to: \.gravity, on: self)
}
} else {
cancellable?.cancel()
}
}
gravityPublisher
本身只是一个 CurrentValueSubject< /code>
private var gravitySubject =
CurrentValueSubject<CMAcceleration, Never>(CMAcceleration())
已删除为 AnyPublisher
。 cancellable
存储为状态属性,如下所示:
@State private var cancellable: Cancellable?
我需要从 SwiftUI 视图中调用此函数。当我从 onAppear 块调用它时,一切都会按预期工作,并且我不断收到重力矢量更新:
struct CustomView: View {
var body: some View {
MyView()
.onAppear {
enableGravityDetection(true)
}
}
}
但是,当我从视图的初始值设定项调用相同(未修改的)函数时,我没有收到任何重力当订阅立即取消时更新:
struct CustomView: View {
init() {
enableGravityDetection(true)
}
var body: some View {
MyView()
}
}
上面流中的 print()
语句在这种情况下打印以下输出:
receive subscription: (ReceiveOn)
request unlimited
receive cancel // ← Why?
为什么会这样以及如何解决这个问题?
我需要在初始化程序中调用此函数,因为有时我需要停止接收重力更新,并且需要在每次重新创建视图时做出决定。 (onAppear
仅调用一次。)
I have created a gravityPublisher
(to receive updates in the current gravity vector) and subscribe to it by calling the following function:
private func enableGravityDetection(_ gravityEnabled: Bool) {
if gravityEnabled {
if cancellable == nil {
cancellable = gravityProvider
.gravityPublisher
.receive(on: RunLoop.main)
.print()
.assign(to: \.gravity, on: self)
}
} else {
cancellable?.cancel()
}
}
The gravityPublisher
itself is just a CurrentValueSubject
private var gravitySubject =
CurrentValueSubject<CMAcceleration, Never>(CMAcceleration())
erased to AnyPublisher<CMAcceleration, Never>
. The cancellable
is stored as a state property as follows:
@State private var cancellable: Cancellable?
I need to call this function from within a SwiftUI view. When I call it from an onAppear
block everything works as expected and I continuously receive gravity vector updates:
struct CustomView: View {
var body: some View {
MyView()
.onAppear {
enableGravityDetection(true)
}
}
}
However, when I call the same (unmodified) function from the view's initializer, I don't receive any gravity updates as the subscription is immediately canceled:
struct CustomView: View {
init() {
enableGravityDetection(true)
}
var body: some View {
MyView()
}
}
The print()
statement in the stream above prints the following output in this case:
receive subscription: (ReceiveOn)
request unlimited
receive cancel // ← Why?
Why is that and how can I fix this?
I need to call this function in the initializer as I sometimes need to stop receiving gravity updates and need to decide this every time the view is recreated. (onAppear
is only called once.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论