快速进行轮询的正确方法?

问题描述 投票:0回答:3

我对其他编程语言有很多经验,但在 swift 3 方面没有那么多经验。我想做轮询循环。这是我写的:

DispatchQueue.global(qos: .userInitiated).async {
            [unowned self] in
            while self.isRunning {
                WebService.getPeople(completion: nil)
                sleep(100)
            }
        }

这对我来说效果很好,每 100 秒,我进行一次轮询,然后让这个线程休眠。我想知道,这是在 swift 3 中执行此操作的正确方法吗?

swift grand-central-dispatch polling
3个回答
15
投票

您有 2 个选择:

  • 使用
    NSTimer
  • 使用
    DispatchSourceTimer

使用

NSTimer
非常简单,但它需要一个活动的运行循环,因此如果您需要轮询后台线程,事情可能会有点棘手,因为您需要创建一个线程并保持运行循环处于活动状态它(可能计时器本身将使运行循环保持活动状态)。
另一方面,
DispatchSourceTimer
使用
queues
工作。您可以轻松地从系统提供的队列之一创建或创建一个调度源计时器。

    var timer: DispatchSourceTimer?
    let queue = DispatchQueue.global(qos: .background)
    guard let timer = DispatchSource.makeTimerSource(queue: queue) else { return }
    timer.scheduleRepeating(deadline: .now(), interval: .seconds(100), leeway: .seconds(1))
    timer.setEventHandler(handler: { 
        // Your code
    })
    timer.resume()

leeway
参数是系统可以推迟计时器的时间。


3
投票

斯威夫特 4 和斯威夫特 5

 var timer: Timer? //declare outside function scope
 var runCount = 0


 self.timer = Timer(timeInterval: 2.0, target: self, selector: #selector(self.fireTimer), userInfo: nil, repeats: true)

 guard let timer = self.timer else {return}
 RunLoop.main.add(self.timer, forMode: RunLoop.Mode.default)

 @objc func fireTimer() {
         print("Timer fired! \(runCount)")
        runCount += 1

        if runCount == 5 {
            timer?.invalidate() //stop the timer
        }
    }

self.timer = Timer.init(timeInterval: 1.0, repeats: true, block: { (timer) in
        print("\n--------------------TIMER FIRED--------------\n")
        runCount += 1
        if runCount == 5{
          timer.invalidate()
    }
    })
guard let timer = self.timer else {return}

RunLoop.main.add(self.timer!, forMode: RunLoopMode.defaultRunLoopMode)

3
投票

Swift 5、iOS 10.0+

接受的答案中的代码不再编译,可以将其修改(并简化!)为:

DispatchQueue.global(qos: .userInitiated).async {
    let timer = Timer.scheduledTimer(withTimeInterval: 10, repeats: true) { timer in
        // Your action
    }
    timer.fire()
}
© www.soinside.com 2019 - 2024. All rights reserved.