在块中调用时 NSTimer 不触发
NSTimer is not firing when called in a block
这个有效
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()
}
这应该可以解决问题。
编辑解释
计时器需要一个活动的 运行 循环。当你在主线程上初始化它时,会自动使用 main 运行 循环。如果您想从后台线程 运行 它,则必须将它附加到该线程 运行 循环。例子
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 评论一致的后台计时器答案
这个有效
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()
}
这应该可以解决问题。
编辑解释
计时器需要一个活动的 运行 循环。当你在主线程上初始化它时,会自动使用 main 运行 循环。如果您想从后台线程 运行 它,则必须将它附加到该线程 运行 循环。例子
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 评论一致的后台计时器答案