[英]why NSTimer works just once in swift
我有一个http请求,如果我正确收到响应,那么我想启动一个每秒触发一个函数的计时器。 该函数也是一个http请求。
这是我启动计时器的代码
if let data = data {
do{
let resultJSON = try NSJSONSerialization.JSONObjectWithData(data, options: [])
requestClient.id = resultJSON["id"] as! Double
self.timerResponse = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "checkIfThereAreResponeses", userInfo: nil, repeats: true)
self.timerResponse!.fire()
}catch{
}
}
如你所见,我正在调用一个名为checkIfThereAreResponses
的函数
在该函数中,我有一个print语句,并且该print语句只打印一次, 尽管我的计时器应该每1秒工作一次
我有什么遗失?
这就是功能
func checkIfThereAreResponeses(){
if (requestClient!.id != nil) {
let url = NSURL(string: "http://localhost:blablabla")
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
let session = NSURLSession.sharedSession()
task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
if let error = error {
print("error = \(error)")
}
if let data = data {
do {
let resultJSONArray = try NSJSONSerialization.JSONObjectWithData(data, options: []) as! NSArray
bla bla bla
}catch {
print("no responses yet = \(error)")
}
}
})
task!.resume()
}else {
print("not yet ")
}
}
我收到JUST ONCE的印刷品no response yet
如果你在完成处理程序中有这个代码,建议NSTimer在主线程中运行,这可能是原因。 您可能需要以下内容:
dispatch_async(dispatch_get_main_queue(), {
// Your timer logic here
})
Apple文档说:
定时器与运行循环一起使用。 要有效地使用计时器,您应该了解运行循环的运行方式 - 请参阅NSRunLoop。
( NSTimer )
NSRunLoop类通常不被认为是线程安全的,并且只应在当前线程的上下文中调用其方法。 您永远不应该尝试调用在不同线程中运行的NSRunLoop对象的方法,因为这样做可能会导致意外结果。
( NSRunLoop )
NSTimer通过在runloop上进行调度来工作。 如果在会话的completionHandler中调用此方法,它将被调度到该completionHandler当前正在运行的线程的runloop。 由于此线程不归您所有,而是由系统拥有,因此它将由系统处理。 这可能是在completionHandler执行完毕后立即执行,或者可能要晚得多。 使用该线程,runloop也会消失,因此,您的计时器可能永远不会发生,几次或只发一次; 真的没有说明,因为它取决于系统何时删除线程。
因此,您应该在您拥有的线程上创建计时器,或者更容易,将计时器的创建分派给主线程( dispatch_get_main_queue()
是您的朋友)。 另一种选择是使用+timerWithTimeInterval...
方法之一创建NSTimer,然后使用[NSRunloop mainRunloop] addTimer: yourTimer forMode NSRunLoopCommonModes]
将其添加到主runloop中。 请记住,计时器将在与运行它的runloop相同的线程上调用选择器。
作为旁注,轮询服务器可能不是移动设备的最佳方式。 如果您控制服务器,最好在有新数据时向设备发送推送通知。 这样可以节省设备上的电量,并减少服务器的负载。 但是,如果您不控制服务器,实现这一点会更复杂,然后轮询可能是一个很好的折衷方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.