ios - Combine: Init mutating 'self' parameter
问题描述
I'm messing around with Combine code and Swift UI and came across this problem. Effectively I want to pass a Publisher
into a View
and have that View
update every time the publisher publishes an update.
Here's a sample playground that will not compile. Instead it puts up an error - Escaping closure captures mutating 'self' parameter
on the .sink(...
line.
import Combine
import SwiftUI
struct MyView: View {
let cancellable: AnyCancellable
@State var current: Int = 0
init<P>(publisher: P) where P: Publisher, P.Output == Int, P.Failure == Never {
cancellable = publisher.sink { value in
self.current = value
}
}
var body: some View {
Text("\(current)")
}
}
let subject = PassthroughSubject<Int, Never>()
let x = MyView(publisher: subject)
subject.send(5)
Currently I've changed the code to use an ObservableObject
view model with the value inside it and telling that object to send an update. But I'm interested how others have gotten around this problem as I'd like a none view model option too.
What have you guys done?
解决方案
您可以使用onReceive
订阅Publisher
SwiftUI 中View
的 Combine 。这样,SwiftUI 运行时将为您管理订阅,即使您的视图可能会被重新创建多次。
struct MyView: View {
@State var current: Int = 0
var body: some View {
Text("\(current)")
.onReceive(somePublisher) { self.current = $0 }
}
}
但是,ObservableObject
直接使用 s 通常是一个更好的主意,因为它们直接集成到 SwiftUI 中。
推荐阅读
- postgresql - 使用 RBAC (Envoy) 允许带有 TCP 侦听器的 IP
- youtube-api - Youtube v3 api 说“超出配额”,但我的使用量为 0
- excel - 将多列合并为具有唯一标识符的一列 - EXCEL
- javascript - 将js数组转换为另一种js数组格式
- django - form.is_valid() 在 Django 中总是返回 False
- reactjs - 将表单数据从子组件发送到父组件
- redis - 如何使用 JMeter 从 Redis 的 Hash 数据结构中获取数据
- websocket - Socket.io 是否支持 WSO2 API Manager Websocket?
- sql - 这些查询的 Oracle 旧语法连接等价物是什么?
- python - 我在处理数据时无法查看数据