Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swiftui 如何通过另一个可观察的0对象观察已发布的属性-Swift Combine_Swiftui_Combine - Fatal编程技术网

Swiftui 如何通过另一个可观察的0对象观察已发布的属性-Swift Combine

Swiftui 如何通过另一个可观察的0对象观察已发布的属性-Swift Combine,swiftui,combine,Swiftui,Combine,[编辑] 我应该指出,我正在从大量传感器收集数据,并且不得不污染视图模型,也就是说,正在协调这一过程,大量的@Published和订户代码变得非常乏味和容易出错 我还编辑了代码,以便更能代表实际问题 [原件] 我试图减少使用发布服务器时观察另一个类的结果所需的代码量。我更愿意从生成结果的类发布结果,而不是将其传播回调用类 下面是一个简单的游乐场示例,说明了这个问题 import SwiftUI import Combine class AnObservableObject: Observabl

[编辑]

我应该指出,我正在从大量传感器收集数据,并且不得不污染视图模型,也就是说,正在协调这一过程,大量的@Published和订户代码变得非常乏味和容易出错

我还编辑了代码,以便更能代表实际问题

[原件] 我试图减少使用发布服务器时观察另一个类的结果所需的代码量。我更愿意从生成结果的类发布结果,而不是将其传播回调用类

下面是一个简单的游乐场示例,说明了这个问题

import SwiftUI
import Combine

class AnObservableObject: ObservableObject {
    
    @Published var flag: Bool = false

    
    private var timerPub: Publishers.Autoconnect<Timer.TimerPublisher>
    
    private var timerSub: AnyCancellable?
    
    init() {
        
        timerPub = Timer.publish(every: 1, on: .current, in: .common)
            .autoconnect()
        
        
    }
    
    func start() {
        timerSub = timerPub.sink { [self] _ in
            toggleFlag()
        }
    }
    
    func stop() {
        timerSub?.cancel()
        
    }
    
    func toggleFlag() {
        flag.toggle()
    }
}

class AnotherObservableObject: ObservableObject {
    let ao = AnObservableObject()
    
    func start() {
        ao.start()
    }
   
    func stop() {
        ao.stop()
    }
    
}

struct MyView: View {
    
    @StateObject var ao = AnotherObservableObject()
    
    var body: some View {
        VStack {
            if ao.ao.flag {
                Image(systemName: "flag").foregroundColor(.green)
            }
            HStack {
                Button(action: {ao.start()}, label: {
                    Text("Toggle Flag")
                })
                Button(action: {ao.stop()}, label: {
                    Text("Stop")
                })
            }
        }
        .padding()
    }
}

import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
// Make a UIHostingController
let viewController = UIHostingController(rootView: MyView())
// Assign it to the playground's liveView
PlaygroundPage.current.liveView = viewController
let myView = MyView()
导入快捷界面
进口联合收割机
类AnObservableObject:ObservableObject{
@已发布变量标志:Bool=false
private var timerPub:publisher.Autoconnect
private var timerSub:是否可以取消?
init(){
timerPub=Timer.publish(每:1,在:。当前,在:。公共)
.自动连接()
}
func start(){
timerSub=timerPub.sink{[self]\uuin
toggleFlag()
}
}
函数停止(){
timerSub?.cancel()
}
func toggleFlag(){
flag.toggle()
}
}
另一个ObserveObject类:ObserveObject{
设ao=AnObservableObject()
func start(){
ao.start()
}
函数停止(){
ao.停止()
}
}
结构MyView:View{
@StateObject var ao=另一个ObservableObject()
var body:一些观点{
VStack{
如果ao.ao.flag{
图像(系统名称:“标志”).foregroundColor(.绿色)
}
HStack{
按钮(操作:{ao.start()},标签:{
文本(“切换标志”)
})
按钮(操作:{ao.stop()},标签:{
文本(“停止”)
})
}
}
.padding()
}
}
导入PlaygroundSupport
PlaygroundPage.current.NeedsDefiniteExecution=true
//制作一个UIHostingController
让viewController=UIHostingController(rootView:MyView())
//将其指定给游乐场的liveView
PlaygroundPage.current.liveView=viewController
让myView=myView()
我实现这一目标的唯一方法是:

import SwiftUI
import Combine

class AnObservableObject: ObservableObject {
    
    let flag = CurrentValueSubject<Bool, Never>(false)

    private var subscriptions = Set<AnyCancellable>()

    
    private var timerPub: Publishers.Autoconnect<Timer.TimerPublisher>
    
    private var timerSub: AnyCancellable?
    
    init() {
        
        timerPub = Timer.publish(every: 1, on: .current, in: .common)
            .autoconnect()
        
        
    }
    
    func start() {
        timerSub = timerPub.sink { [self] _ in
            toggleFlag()
        }
    }
    
    func stop() {
        timerSub?.cancel()
        
    }
    
    func flagPublisher() -> AnyPublisher<Bool, Never> {
        return flag.eraseToAnyPublisher()
    }
    
    func toggleFlag() {
        flag.value.toggle()
    }
}

class AnotherObservableObject: ObservableObject {
    let ao = AnObservableObject()
    
    @Published var flag = false
    
    
    
    init() {


        let flagPublisher = ao.flagPublisher()

        flagPublisher
            .receive(on: DispatchQueue.main)
            .assign(to: &$flag)
    }
    
    func start() {
        ao.start()
    }
   
    func stop() {
        ao.stop()
    }
    
}

struct MyView: View {
    
    @StateObject var ao = AnotherObservableObject()
    
    var body: some View {
        VStack {
            if ao.flag {
                Image(systemName: "flag").foregroundColor(.green)
            }
            HStack {
                Button(action: {ao.start()}, label: {
                    Text("Toggle Flag")
                })
                Button(action: {ao.stop()}, label: {
                    Text("Stop")
                })
            }
        }
        .padding()
    }
}

import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
// Make a UIHostingController
let viewController = UIHostingController(rootView: MyView())
// Assign it to the playground's liveView
PlaygroundPage.current.liveView = viewController
let myView = MyView()
导入快捷界面
进口联合收割机
类AnObservableObject:ObservableObject{
let flag=CurrentValueSubject(false)
私有变量订阅=Set()
private var timerPub:publisher.Autoconnect
private var timerSub:是否可以取消?
init(){
timerPub=Timer.publish(每:1,在:。当前,在:。公共)
.自动连接()
}
func start(){
timerSub=timerPub.sink{[self]\uuin
toggleFlag()
}
}
函数停止(){
timerSub?.cancel()
}
func flagPublisher()->AnyPublisher{
return flag.eraseToAnyPublisher()
}
func toggleFlag(){
flag.value.toggle()
}
}
另一个ObserveObject类:ObserveObject{
设ao=AnObservableObject()
@发布的var标志=false
init(){
让flagPublisher=ao.flagPublisher()
旗舰出版商
.receive(在:DispatchQueue.main上)
.分配(给:&$flag)
}
func start(){
ao.start()
}
函数停止(){
ao.停止()
}
}
结构MyView:View{
@StateObject var ao=另一个ObservableObject()
var body:一些观点{
VStack{
如果是ao旗{
图像(系统名称:“标志”).foregroundColor(.绿色)
}
HStack{
按钮(操作:{ao.start()},标签:{
文本(“切换标志”)
})
按钮(操作:{ao.stop()},标签:{
文本(“停止”)
})
}
}
.padding()
}
}
导入PlaygroundSupport
PlaygroundPage.current.NeedsDefiniteExecution=true
//制作一个UIHostingController
让viewController=UIHostingController(rootView:MyView())
//将其指定给游乐场的liveView
PlaygroundPage.current.liveView=viewController
让myView=myView()

想法?

你不需要一个
可观察对象来实现这一点;您可以直接在
视图中观察
计时器

struct MyView: View {
    
    @State private var flag: Bool = false
    
    @State var timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
    
    var body: some View {
        VStack {
            if flag {
                Image(systemName: "flag").foregroundColor(.green)
            }
            
            HStack {
                Button(action: {start()}, label: {
                    Text("Toggle Flag")
                })
                Button(action: {stop()}, label: {
                    Text("Stop")
                })
            }
            .onReceive(timer) { _ in
                flag.toggle()
            }
        }
        .padding()
    }
    
    func start() {
        timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
    }
    
    func stop() {
        timer.upstream.connect().cancel()
    }
}

当您需要在视图中直接使用它时,通常需要一个
可观察对象。你为什么需要一个?如果你没有,你可以只使用一个struct而不是
AnObservableObject
,希望在几周内。你现在这样做是唯一的连锁方式them@loremipsum谢谢,希望如此!如果SwitftUI、Combine和pro Mac获得重大更新,则应为退出活动!谢谢你的回答,我现在已经更新了我的代码,并希望提供更好的解释。考虑收集位置数据,操作它,然后将一些结果传递给视图,我想这样做,而不必将这些返回到VIEW模型。这只是我收集的数据点之一。