[背景]
swift中,仿照之前的用法去写了个timer:
|     func startWsKeepConnectTimer() {         print("startWsKeepConnectTimer")         self.wsKeepConnectCounter = self.wsKeepConnectInterval         self.wsKeepConnectTimer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector:Selector("updateWsKeepConnectCounter"), userInfo: nil, repeats: true)     }     func updateWsKeepConnectCounter() {         print("updateWsKeepConnectCounter self.wsKeepConnectCounter=\(self.wsKeepConnectCounter)")         self.wsKeepConnectCounter -= 1         if self.wsKeepConnectCounter <= 0 {             self.wsKeepConnectCounter = self.wsKeepConnectInterval             websocketKeepConnect()         }     } | 
结果不工作:
后续的updateWsKeepConnectCounter没有执行到。
[解决过程]
1.以为是当前viewcontroller的问题,所以换为:
| //        self.wsKeepConnectTimer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector:Selector("updateWsKeepConnectCounter"), userInfo: nil, repeats: true)         self.wsKeepConnectTimer = NSTimer.scheduledTimerWithTimeInterval(1, target: SingletonMainVC(), selector:Selector("updateWsKeepConnectCounter"), userInfo: nil, repeats: true) | 
还是不行。
2.搜:
swift timer not firing
参考:
Using an NSTimer in Swift – Stack Overflow
ios – NSTimer not working Swift – Stack Overflow
3.搜:
swift scheduledTimerWithTimeInterval not firing
参考:
NSTimer.scheduledTimerWithTimeInterval in Swift Playground – Stack Overflow
加上fire试试:
self.wsKeepConnectTimer.fire()
但是要说明的是:
之前用这个NSTimer.scheduledTimerWithTimeInterval,都不需要手动调用fire就可以自动工作的。
结果fire只使得:
updateWsKeepConnectCounter
运行了一次,就停止了。。
NSTimer Not working swift | Apple Developer Forums
把整个timer的代码都放到另外一个viewcontroller:MainViewController中,结果也还是不工作。。。
swift scheduledtimerwithtimeinterval not working
4.突然发现:
难道是因为:
之前可以正常工作的timer,当时调用NSTimer.scheduledTimerWithTimeInterval是出于UI的主线程-》主线程有Loop
而此处调用的NSTimer.scheduledTimerWithTimeInterval时,是http的的callback-》不是住处主线程,没有Loop的环境,所以就没有效果?
此处去改为:
|     func startWsKeepConnectTimer() {         dispatch_async(dispatch_get_main_queue(), { () -> Void in             print("startWsKeepConnectTimer")             self.wsKeepConnectCounter = self.wsKeepConnectInterval             self.wsKeepConnectTimer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector:Selector("updateWsKeepConnectCounter"), userInfo: nil, repeats: true)             //        self.wsKeepConnectTimer = NSTimer.scheduledTimerWithTimeInterval(1, target: SingletonMainVC(), selector:Selector("updateWsKeepConnectCounter"), userInfo: nil, repeats: true)             //        self.wsKeepConnectTimer.fire()         })     } | 
看看效果。
果然可以了:

[总结]
当使用NSTimer.scheduledTimerWithTimeInterval时,要确保:
1.当前处于有Loop的环境
一般来说,当前的UI主界面就是可以的。
所以,如果不是处于主界面时,则去使用:
|     func startWsKeepConnectTimer() {         //Note: makesure when call NSTimer.scheduledTimerWithTimeInterval, need in Loop environment         //so here need in main queue         dispatch_async(dispatch_get_main_queue(), { () -> Void in             print("startWsKeepConnectTimer in main queue")             self.wsKeepConnectTimer = NSTimer.scheduledTimerWithTimeInterval(                 NSTimeInterval(WebsocketKeepConnectIntervalInSec),                 target: self,                 selector:Selector("websocketKeepConnect"),                 userInfo: nil,                 repeats: true)         })     } | 
即可。
2.要确保计时器的目标接收者始终是有效的
即:
使用NSTimer.scheduledTimerWithTimeInterval时的target参数时
此处一般设置为self,即当前的ViewController
但是要确保此处的当前的ViewController是有效的
一些特殊情况比如:
当前处于Login的登录界面时使用的NSTimer.scheduledTimerWithTimeInterval,传递的self时Login的ViewController
结果登录完成,跳转到其他页面时,而销毁了登录界面
然后就会导致计时器下次调用时,找不到接受者而出错
转载请注明:在路上 » [已解决]swift中timer NSTimer.scheduledTimerWithTimeInterval不工作