【问题标题】:Swift Combine .repeat快速组合 .repeat
【发布时间】:2019-07-12 00:02:20
【问题描述】:

我想创建一个重复功能,使用 Combine 在我的代码中创建一个循环。我注意到,Combine 没有通过这个伟大的 repo 重复发布者:https://github.com/freak4pc/rxswift-to-combine-cheatsheet。这是我编写的用于重复 2 个状态的代码。如何将其简化为更具可读性或创建自己的重复功能?

toggleShouldDisplay = Just<Void>(())
  .delay(for: 2, scheduler:RunLoop.main)
  .map({ _ in
    self.shouldDisplay = true
    self.didChange.send(())
  })
  .delay(for: 2, scheduler: RunLoop.main)
  .map({ _ in
    self.shouldDisplay = false
    self.didChange.send(())
  })
  .setFailureType(to: NSError.self)
  .tryMap({ _ in
    throw NSError()
  })
  .retry(.max) // I might hit Int.max if I reduce the delays
  .sink(receiveValue: { _ in
    //Left empty
  })

【问题讨论】:

    标签: swift reactive-programming combine


    【解决方案1】:

    .retry(_:) 运算符实际上旨在用于重试可能失败的操作,例如网络请求。听起来你需要一个计时器。幸运的是,从 Xcode 11 beta 2 开始,Apple 已将 Publisher 支持添加到 Foundation 中的 Timer 类。

    关于您的实现的另一条评论:我假设此代码用于BindableObject,因为您正在访问didChange。既然didChange 可以是任何类型的Publisher,为什么不将shouldDisplay 属性用作Publisher

    final class MyModel: BindableObject {
        var didChange: CurrentValueSubject<Bool, Never> { shouldDisplaySubject }
        var shouldDisplay: Bool { shouldDisplaySubject.value }
    
        private let shouldDisplaySubject = CurrentValueSubject<Bool, Never>(false)
        private var cancellables: Set<AnyCancellable> = []
    
        init() {
            startTimer()
        }
    
        private func startTimer() {
            Timer.publish(every: 2, on: .main, in: .default)
                .autoconnect()
                .scan(false) { shouldDisplay, _ in
                    !shouldDisplay
                }
                .assign(to: \.value, on: shouldDisplaySubject)
                .store(in: &cancellables)
        }
    }
    

    【讨论】:

      【解决方案2】:

      你可以像这样使用Timer.Publisher

      toggleShouldDisplay = Timer.publisher(every: 2, on: .main, in: .default)
        .autoconnect()
        .sink {
          self.shouldDisplay = !self.shouldDisplay
          self.didChange.send(())
        }
      

      autconnect()Timer 在您使用sink(_:) 订阅后立即启动。

      【讨论】:

        猜你喜欢
        • 2020-05-19
        • 1970-01-01
        • 2020-05-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-11
        • 2019-03-11
        • 2015-03-20
        相关资源
        最近更新 更多