RunLoop是一让线程能随时处理事件但不退出的机制。RunLoop 实际上是一个对象,这个对象管理了其需要处理的事件和消息,并提供了一个入口函数来执行Event Loop 的逻辑。线程执行了这个函数后,就会一直处于这个函数内部 “接受消息->等待->处理” 的循环中,直到这个循环结束(比如传入 quit 的消息),函数返回。让线程在没有处理消息时休眠以避免资源占用、在有消息到来时立刻被唤醒。
Runloop原理.png
do{
//通知将要处理timer和source
__CFRunLoopDoObservers(kCFRunLoopBeforeTimers);
__CFRunLoopDoObservers(kCFRunLoopBeforeSources);
__CFRunLoopDoBlocks();//处理非延迟的注线程调用
__CFRunLoopDoSource0();//处理UIEVent事件
//GCD dispatch main queue
CheckIfExistMessagesInMainDispatchQueue();
//即将进入休眠
__CFRunLoopDoObservers(kCFRunLoopBeforeWaiting);
//等待内核mach_msg事件
mach_port_t wakeupPort = SleepAndWaitForWakingUpPorts();
//Zzzz.....
//从等待中醒来
__CFRunLoopDoObservers(kCFRunLoopAfterWaiting);
//处理因timer的唤醒
if(wakeUpPort == timerPort)
__CFRunLoopDoTimers();
//处理异步方法唤醒,如dispatch_asyn
else if(wakeUpPort == mainDispatchQueuePort)
__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__()
//UI刷新,动画显示
else
__CFRunLoopDoSource1();
//再次确保是否有同步的方法需要调用
__CFRunLoopDoBlocks();
}while(!stop && timeout);