[背景]
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不工作