Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 在块中调用NSTimer时未触发_Swift_Nstimer - Fatal编程技术网

Swift 在块中调用NSTimer时未触发

Swift 在块中调用NSTimer时未触发,swift,nstimer,Swift,Nstimer,这很有效 func startTimer () { batchTimer = NSTimer.scheduledTimerWithTimeInterval(batchIntervalSeconds, target: self, selector: #selector(Requester.performRemoteRequests), userInfo: nil, repeats: false) } 这并不重要 func startTimerInBlock () { let

这很有效

 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\u块内

 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()
  }
但是,如果您想确保它只从主线程运行,只需从dispatch main闭包启动它,它将确保它将运行主线程

编辑:为Swift 3更新


编辑2:更新为显示符合Phil Mitchells评论的后台计时器答案

实际上,您可以在后台线程上运行计时器,但需要