原因在于滑动时当前线程的runloop切换了mode用于列表滑动,导致timer暂停。
runloop中的mode主要用来指定事件在runloop中的优先级,有以下几种:
Default(NSDefaultRunLoopMode):默认,一般情况下使用;Connection(NSConnectionReplyMode):一般系统用来处理NSConnection相关事件,开发者一般用不到;Modal(NSModalPanelRunLoopMode):处理modal panels事件;Event Tracking(NSEventTrackingRunLoopMode):用于处理拖拽和用户交互的模式。Common(NSRunloopCommonModes):模式合集。默认包括Default,Modal,Event Tracking三大模式,可以处理几乎所有事件。
回到题中的情境。滑动列表时,runloop的mode由原来的Default模式切换到了Event Tracking模式,timer原来好好的运行在Default模式中,被关闭后自然就停止工作了。
解决方法其一是将timer加入到NSRunloopCommonModes中。其二是将timer放到另一个线程中,然后开启另一个线程的runloop,这样可以保证与主线程互不干扰,而现在主线程正在处理页面滑动。示例代码如下:
// 方法1[[NSRunLoopcurrentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];// 方法2dispatch_async(dispatch_get_global_queue(0,0), ^{ timer = [NSTimerscheduledTimerWithTimeInterval:1target:selfselector:@selector(repeat:) userInfo:nilrepeats:true]; [[NSRunLoopcurrentRunLoop] run];});
作者:Silence_广
链接:https://www.jianshu.com/p/15db5e5f2c49
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。