IOS开发中NSRunloop跟NSTimer的问题

咱们在使用NSTimer的时候,可能会接触到runloop的概念,下面是一个简单的例子:服务器

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval:1
                                              target:self
                                            selector:@selector(printMessage:)
                                            userInfo:nil
                                             repeats:YES];
}框架

 

这个时候若是咱们在界面上滚动一个scrollview,那么咱们会发如今中止滚动前,控制台不会有任何输出,就好像scrollView在滚动的时候将timer暂停了同样,在查看相应文档后发现,这其实就是runloop的mode在作怪。
runloop 能够理解为cocoa下的一种消息循环机制,用来处理各类消息事件,咱们在开发的时候并不须要手动去建立一个runloop,由于框架为咱们建立了一个默 认的runloop,经过[NSRunloop currentRunloop]咱们能够获得一个当前线程下面对应的runloop对象,不过咱们须要注意的是不一样的runloop之间消息的通知方式。异步

接着上面的话题,在开启一个NSTimer实质上是在当前的runloop中注册了一个新的事件源,而当scrollView滚动的时候,当前的 MainRunLoop是处于UITrackingRunLoopMode的模式下,在这个模式下,是不会处理NSDefaultRunLoopMode 的消息(由于RunLoop Mode不同),要想在scrollView滚动的同时也接受其它runloop的消息,咱们须要改变二者之间的runloopmode.oop

 

[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

简单的说就是NSTimer不会开启新的进程,只是在Runloop里注册了一下,Runloop每次loop时都会检测这个timer,看是否可 以触发。当Runloop在A mode,而timer注册在B mode时就没法去检测这个timer,因此须要把NSTimer也注册到A mode,这样就能够被检测到。线程

说到这里,在http异步通讯的模块中也有可能碰到这样的问题,就是在向服务器异步获取图片数据通知主线程刷新tableView中的图片时,在 tableView滚动没有中止或用户手指停留在屏幕上的时候,图片一直不会出来,可能背后也是这个runloop的mode在作怪,嘿嘿。对象

相关文章
相关标签/搜索