在Windows时代,你们确定对SendMessage,PostMessage,GetMessage有所了解,这些都是windows中的消 息处理函数,那对应在ios中是什么呢,其实就是NSRunloop这个东西。在ios中,全部消息都会被添加到NSRunloop中,分为‘input source’跟'timer source'种,并在循环中检查是否是有事件须要发生,若是须要那么就调用相应的函数处理。ios
咱们在使用NSTimer的时候,可能会接触到runloop的概念,windows
下面是一个简单的例子服务器
- (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.函数
1 [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
简单的说就是NSTimer不会开启新的进程,只是在Runloop里注册了一下,Runloop每次loop时都会检测这个timer,看是否可 以触发。当Runloop在A mode,而timer注册在B mode时就没法去检测这个timer,因此须要把NSTimer也注册到A mode,这样就能够被检测到。oop
说到这里,在http异步通讯的模块中也有可能碰到这样的问题,就是在向服务器异步获取图片数据通知主线程刷新tableView中的图片时,在 tableView滚动没有中止或用户手指停留在屏幕上的时候,图片一直不会出来,可能背后也是这个runloop的mode在作怪
出处: http://www.cnblogs.com/xwang/spa