Swift - 带有条件的 GCD 计时器
Posted
技术标签:
【中文标题】Swift - 带有条件的 GCD 计时器【英文标题】:Swift - Timer with GCD with condition 【发布时间】: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 值的条件。 有什么想法吗?
非常感谢,
【问题讨论】:
【参考方案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
)
【讨论】:
以上是关于Swift - 带有条件的 GCD 计时器的主要内容,如果未能解决你的问题,请参考以下文章
Swift3.0 GCD定时器的使用,实现倒计时,UIDatePicker的使用, 仿写一个活动倒计时的DEMO