/********************************************************************************************
* author:conowen@大钟
* E-mail:[email protected]
* http://blog.csdn.net/conowen
********************************************************************************************/
void CFRunLoopRun(void) { /* DOES CALLOUT */
int32_t result;
do {//就是一个do while循环
result = CFRunLoopRunSpecific(CFRunLoopGetCurrent(), kCFRunLoopDefaultMode, 1.0e10, false);
CHECK_FOR_FORK();
} while (kCFRunLoopRunStopped != result && kCFRunLoopRunFinished != result);
}
SInt32 CFRunLoopRunInMode(CFStringRef modeName, CFTimeInterval seconds, Boolean returnAfterSourceHandled) { /* DOES CALLOUT */
CHECK_FOR_FORK();
return CFRunLoopRunSpecific(CFRunLoopGetCurrent(), modeName, seconds, returnAfterSourceHandled);
}
SInt32 CFRunLoopRunSpecific(CFRunLoopRef rl, CFStringRef modeName, CFTimeInterval seconds, Boolean returnAfterSourceHandled) { /* DOES CALLOUT */
CHECK_FOR_FORK();
if (__CFRunLoopIsDeallocating(rl)) return kCFRunLoopRunFinished;
__CFRunLoopLock(rl);
CFRunLoopModeRef currentMode = __CFRunLoopFindMode(rl, modeName, false);
if (NULL == currentMode || __CFRunLoopModeIsEmpty(rl, currentMode, rl->_currentMode)) {
Boolean did = false;
if (currentMode) __CFRunLoopModeUnlock(currentMode);
__CFRunLoopUnlock(rl);
return did ? kCFRunLoopRunHandledSource : kCFRunLoopRunFinished;
}
volatile _per_run_data *previousPerRun = __CFRunLoopPushPerRunData(rl);
CFRunLoopModeRef previousMode = rl->_currentMode;
rl->_currentMode = currentMode;
int32_t result = kCFRunLoopRunFinished;
if (currentMode->_observerMask & kCFRunLoopEntry ) __CFRunLoopDoObservers(rl, currentMode, kCFRunLoopEntry);
result = __CFRunLoopRun(rl, currentMode, seconds, returnAfterSourceHandled, previousMode);
if (currentMode->_observerMask & kCFRunLoopExit ) __CFRunLoopDoObservers(rl, currentMode, kCFRunLoopExit);
__CFRunLoopModeUnlock(currentMode);
__CFRunLoopPopPerRunData(rl, previousPerRun);
rl->_currentMode = previousMode;
__CFRunLoopUnlock(rl);
return result;
}
//获得RunLoop对象
//Foundation NSRunLoop
[NSRunLoop currentRunLoop]; // 获得当前线程的RunLoop对象
[NSRunLoop mainRunLoop]; // 获得主线程的RunLoop对象
//Core Foundation NSRunLoop
CFRunLoopGetCurrent(); // 获得当前线程的RunLoop对象
CFRunLoopGetMain(); // 获得主线程的RunLoop对象
当RunLoop的准备运行的时候
当RunLoop准备处理一个Timer sources的时候
当RunLoop准备处理一个input sources的时候
当RunLoop准备休眠的时候
当RunLoop被唤醒时,准备执行这个事件的时候
/* Run Loop Observer Activities */
typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
kCFRunLoopEntry = (1UL << 0),
kCFRunLoopBeforeTimers = (1UL << 1),
kCFRunLoopBeforeSources = (1UL << 2),
kCFRunLoopBeforeWaiting = (1UL << 5),
kCFRunLoopAfterWaiting = (1UL << 6),
kCFRunLoopExit = (1UL << 7),
kCFRunLoopAllActivities = 0x0FFFFFFFU
};
Default |
|
The default mode is the one used for most operations. Most of the time, you should use this mode to start your run loop and configure your input sources. Default模式,一般情况下应使用此Mode。主线程RunLoop启动的就是默认模式 |
Connection |
|
Cocoa uses this mode in conjunction with 使用这个Mode来监控NSConnection对象的回复,用户基本不会使用此Mode。 |
Modal |
|
Cocoa uses this mode to identify events intended for modal panels. 使用这个Mode来处理modal panels的事件 |
Event tracking |
|
Cocoa uses this mode to restrict incoming events during mouse-dragging loops and other sorts of user interface tracking loops. 处理用户的一些拖动事件,如UIScrollView的滚动 |
Common modes |
|
This is a configurable group of commonly used modes. Associating an input source with this mode also associates it with each of the modes in the group. For Cocoa applications, this set includes the default, modal, and event tracking modes by default. Core Foundation includes just the default mode initially. You can add custom modes to the set using theCFRunLoopAddCommonMode funtion. 事实上这并不是一个Mode,这只是有关联关系的“Mode”,像一个“标识”,如果设置RunLoop的Mode为这个模式,就可以把Sources同时添加到RunLoop的 default、modal、event tracking模式中(下面用一个场景解释这个到底有啥用) |
获取当前线程的RunLoop Mode
NSString* runLoopMode = [[NSRunLoop currentRunLoop] currentMode];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode]
//直接把NSTimer添加到Event Tracking模式中
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
//设置Common Modes,把NSTimer同时添加到defaul、modal、Event Tracking模式中