【问题标题】:Swift - Timer with GCD with conditionSwift - 带有条件的 GCD 计时器
【发布时间】:2018-12-26 10:08:05
【问题描述】:

我使用 Firebase 上传带有进度指示器的文件:

RappleActivityIndicatorView.setProgress(CGFloat(a), textValue: "\(String(a * 100)) %")
print("\(a) %")

我想实现一个条件:如果 % 的值(例如:23%)被卡住 15 秒或更长时间,它会取消上传。

我在想一个 GCD 计时器:

 DispatchQueue.main.asyncAfter(deadline: .now() + 15) {
        print("We can launch the cancellation of the upload")
    }

但我不知道如何链接 15 秒内未更新的 a 值的条件。 有什么想法吗?

非常感谢,

【问题讨论】:

    标签: swift timer swift4 grand-central-dispatch dispatch-queue


    【解决方案1】:

    一个合适的解决方案是超时计时器。 GCD 计时器的好处是它可以在运行时重新启动。

    你需要一个属性,定时器引用

    var timeoutTimer : DispatchSourceTimer?
    

    然后创建一个方法来启动计时器。如果它没有运行,则创建(单次)计时器,如果它正在运行,则重新启动它。在 15 秒后执行的事件处理程序中,打印该行并释放计时器。

    func startTimeoutTimer()
    {
        let delay : DispatchTime = .now() + .seconds(15)
        if timeoutTimer == nil {
            timeoutTimer = DispatchSource.makeTimerSource(queue: DispatchQueue.global())
            timeoutTimer!.schedule(deadline: delay, repeating: 0)
            timeoutTimer!.setEventHandler {
                self.timeoutTimer!.cancel()
                self.timeoutTimer = nil
                print("We can launch the cancellation of the upload")
            }
            timeoutTimer!.resume()
        } else {
            timeoutTimer?.schedule(deadline: delay, repeating: 0)
        }
    }
    

    要控制计时器,您需要当前百分比值的另一个属性

    var currentValue : CGFloat = 0.0
    

    当设置过程时,将值与当前值进行比较,如果值不同,则(重新)启动计时器。如果值相等,则计时器会在 15 秒延迟后触发。如果进度继续,例如 8 秒后计时器再次从零开始。

    RappleActivityIndicatorView.setProgress(CGFloat(a), textValue: "\(String(a * 100)) %")
    if a != currentValue {
        startTimeoutTimer()
        currentValue = a
    } 
    

    上传成功后删除计时器

    self.timeoutTimer!.cancel()
    self.timeoutTimer = nil
    

    【讨论】:

      【解决方案2】:

      试试这个:

      var timer: Timer?
      
      // every time you set new percent start new Timer. if in 15 sec it will not reach new percent -> cancellation begins
      func startNewTimer() {
          timer?.invalidate()
          timer = Timer.scheduledTimer(withTimeInterval: 15, repeats: false, block: { (_) in
              // do cancellation
          })
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-02-28
        • 2015-09-20
        • 1970-01-01
        • 1970-01-01
        • 2020-12-05
        • 1970-01-01
        • 2014-07-24
        相关资源
        最近更新 更多