首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ObservableObject与条件

ObservableObject与条件
EN

Stack Overflow用户
提问于 2020-02-27 11:20:39
回答 3查看 368关注 0票数 0

我有一个定时器的代码,它会自动启动,并且应该用if语句再次停止。不幸的是,这不起作用,我也没有收到错误信息。我在这里做错什么了?

代码语言:javascript
复制
import SwiftUI
import Combine
import Foundation

class WaitingTimerClass: ObservableObject {

    @Published var waitingTimerCount: Int = 0
    var waitingTimer = Timer()

    func start() {
        self.waitingTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer  in self.waitingTimerCount += 1 } }

    func stop() { waitingTimer.invalidate() }

    func reset() { waitingTimerCount = 0; waitingTimer.invalidate() }

}

struct ContentView: View {

    @ObservedObject var observed = WaitingTimerClass()

    var body: some View {

        Text("\(self.observed.waitingTimerCount)")
            .onAppear {
                self.observed.start()
                    if self.observed.waitingTimerCount == 3 {
                        self.observed.stop()
                        }
                    }
        }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}



``
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-02-27 11:40:20

onAppear块中的代码只工作一次,当View出现时(或多次,当视图消失并再次出现时)。在您的例子中,waitingTimerCount将始终是0。如果您需要从视图中观察一些值,请使用onReceive。代码应该如下所示:

代码语言:javascript
复制
struct TimerWaiter: View {

    @ObservedObject var observed = WaitingTimerClass()

    var body: some View {

        Text("\(self.observed.waitingTimerCount)")
            .onAppear {
                self.observed.start()
        }
        .onReceive(observed.$waitingTimerCount) { count in
            guard count == 3 else { return }
            self.observed.stop()
        }
    }

}

更新的第一作者的评论:我不知道,为什么重发计时器没有工作的预期,我今天没有太多的时间。也许明天会更容易理解。这里不是很好,但有效的解决方案:

代码语言:javascript
复制
class WaitingTimerClass: ObservableObject {

    @Published var waitingTimerCount: Int = 0
    var didInvalidate = PassthroughSubject<Void, Never>()
    var waitingTimer = Timer()

    func start() {
        self.waitingTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer  in self.waitingTimerCount += 1 } }

    func stop() { waitingTimer.invalidate() }

    func reset() {
        waitingTimer.invalidate()
        waitingTimerCount = 0
        didInvalidate.send()

    }

}

struct TimerWaiter: View {

    @ObservedObject var observed = WaitingTimerClass()
    @State private var count = 0

    var body: some View {

        Text("\(count)")
            .onAppear {
                self.observed.start()
        }
        .onReceive(observed.$waitingTimerCount) { count in
            self.count = count
            guard count == 3 else { return }
            self.observed.reset()
        }
        .onReceive(observed.didInvalidate) { _ in
            self.count = 0
        }
    }

}

P.S.我将尝试更深入地了解为什么waitingTimerCount的最后一次变化不会影响视图

票数 0
EN

Stack Overflow用户

发布于 2020-02-27 11:36:08

代码语言:javascript
复制
.onAppear {
    self.observed.start()
    if self.observed.waitingTimerCount == 3 {
        self.observed.stop()
    }
}

这段代码是如何工作的?

当视图出现时它正在运行(很可能只有一次)

  1. 启动计时器
  2. 检查是否waitinigTimer == 3 //它不是3,此时
  3. 返回

所以,就像你已经知道的,它永远不会停止。

如果您想停止waitingTimer == 3,则必须在您的模型中这样做。

代码语言:javascript
复制
@Published var waitingTimerCount: Int = 0 {
    willSet {
        if newValue == 3 { stop() }
    }    
}
票数 0
EN

Stack Overflow用户

发布于 2020-03-01 17:57:50

非常感谢。重置问题的解决方案可以在这里找到:

ObservableObject bug or not

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60432112

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档