这有效

 func startTimer () {
    batchTimer = NSTimer.scheduledTimerWithTimeInterval(batchIntervalSeconds, target: self, selector: #selector(Requester.performRemoteRequests), userInfo: nil, repeats: false)

}

这不是
func startTimerInBlock () {
    let urlRequest = NSMutableURLRequest(URL: NSURL(string: "google.com")!, cachePolicy: .ReloadIgnoringLocalCacheData , timeoutInterval: 30)
    urlRequest.HTTPMethod = "GET"
    let session = NSURLSession(configuration: NSURLSessionConfiguration.ephemeralSessionConfiguration())
    let task = session.dataTaskWithRequest(urlRequest) { (data:NSData?, response:NSURLResponse?, error:NSError?) -> Void in
        //check there is a response and that it is an http response
        self.batchTimer = NSTimer.scheduledTimerWithTimeInterval(self.batchIntervalSeconds, target: self, selector: #selector(CNVRRequester.performRemoteRequests), userInfo: nil, repeats: false)

    }
    task.resume()
}

有人知道为什么在块中调用的计时器不触发吗?

最佳答案

简单修复,将self.startTimer代码放在dispatch_block内

 DispatchQueue.main.async {
        self.startTimer()
 }

那应该解决它。

编辑解释

计时器需要一个事件的运行循环。在主线程上初始化它时,将自动使用主运行循环。如果要从后台线程运行它,则必须将其附加到该线程运行循环。例子
DispatchQueue.global(qos: .background).async {
    let timer = Timer.scheduledTimer(timeInterval: 10, target: self, selector: selector(fireTimer), repeats: false)
    let runLoop = RunLoop.current
    runLoop.add(timer, forMode: .defaultRunLoopMode)
    runLoop.run()
  }

但是,如果要确保它仅从主线程运行,则只需从调度主闭包启动它,这将确保它将运行主线程。

编辑:为Swift 3更新

编辑2:已更新,以显示后台计时器答案,与Phil Mitchells的评论一致

关于swift - 在块中调用NSTimer时不触发,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36747869/

10-14 20:46