2015-04-04 145 views
1

UIViewController中,我有一个NSTimer计划每隔1秒触发一次,使用scheduledTimer方法,所以我可以每秒在视图中更新一个UILabel。但问题是,NSTimer开火似乎被延迟,只要我在UIView内的MKMapView周围摇晃。所以延迟导致UILabel不是统一更新,这是不好看的。由MKMapView平移导致的延迟是否会占用太多资源?我如何安排NSTimer,以便不会有任何延迟,但我平移MKMapView? (但是,请注意,我没有在某种后台线程上安排NSTimer,它在主线程中。)谢谢。NSTimer似乎被MKMapView平移减慢了?

+0

是否在后台线程中设置了定时器来做计算,然后用'dispatch_async'获取主线程来更新UI,工作? dispatch_async示例显示在此asnwer:http://stackoverflow.com/questions/16283652/understanding-dispatch-async – Zhang 2015-04-04 13:19:52

+0

你是如何安排计时器?如果您希望它在滚动/平移时触发,则需要使用“NSRunLoopCommonModes”来安排它。 – dan 2015-04-04 14:00:03

回答

3

如果您使用scheduledTimerWithTimeInterval(...)来创建您的计时器,它将被添加到模式为NSDefaultRunLoopMode的当前runloop。计时器不会在您的应用程序忙于事件跟踪时触发,即如果您在UIScrollView中滚动,或者如果您与UI进行任何其他交互。

如果您使用NSRunLoopCommonModes作为模式,则计时器将在您与用户界面进行交互时触发,您可以创建一个未计划的NSTimer并将其自动添加到runloop中。

let timer = NSTimer(timeInterval: 1.0, target: self, selector: Selector("timerFired:"), userInfo: nil, repeats: true) 
NSRunLoop.currentRunLoop().addTimer(timer, forMode: NSRunLoopCommonModes) 

如需进一步信息,问题NSDefaultRunLoopMode vs NSRunLoopCommonModes包含了不同runloop模式一个很好的解释。

+0

谢谢,但有一个问题...应用程序注册后台位置更新,我用来获取位置更新的CLLocationManager是延迟更新启用。我试图用NSRunLoopCommonModes将计时器添加到运行循环中,但似乎系统在运行时间过长时会终止该应用。我认为这是因为当运行循环应该被禁用时,NSTimer正在占用NSRunLoop。 – Blip 2015-04-04 21:44:51

+0

如果应用程序进入后台,则会使计时器无效,并在应用程序再次进入前台时重新创建它 – 2015-04-05 10:45:13

+0

谢谢您的天才建议解决了我的问题。 – Blip 2015-04-07 21:44:37