tableView加载过多的高清大图,Runloop不只处理iOS事件,渲染图形也是runloop处理的。
Source1/Timer/Observer _currentMode:RunLoop当前的运行模式 _modes:存储着RunLoop所有的 Mode(CFRunLoopModeRef)模式 // CFRunLoop.h...typedef struct __CFRunLoop * CFRunLoopRef; // CFRunLoop.c struct __CFRunLoop { pthread_t _pthread...// CFRunLoop.h typedef struct __CFRunLoopMode *CFRunLoopModeRef; // CFRunLoop.c struct __CFRunLoopMode...// CFRunLoop.h typedef struct __CFRunLoopSource * CFRunLoopSourceRef; // CFRunLoop.m struct __CFRunLoopSource...// CFRunLoop.h typedef struct CF_BRIDGED_MUTABLE_TYPE(NSTimer) __CFRunLoopTimer * CFRunLoopTimerRef;
__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__(kCFRunLoopBeforeTimers); /// 3....__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__(kCFRunLoopBeforeSources); __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK...__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__(source0); __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK...通知Observers,线程被唤醒 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__(kCFRunLoopAfterWaiting...如果是被Timer唤醒的,回调Timer __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__(timer);
一、CFRunLoop部分源码 阅读源码:CFRunLoop.c CFRunLoopRef CFRunLoopGetCurrent(void) { CHECK_FOR_FORK(); CFRunLoopRef...RunLoop有5个类 CFRunLoopRef CFRunLoopModelRef CFRunLoopSourceRef CFRunLoopTimerRef CFRunLoopObserverRef 2、CFRunLoop...struct __CFRunLoop { CFRuntimeBase _base; pthread_mutex_t _lock; /* locked for accessing mode...= MACH_PORT_NULL && livePort == modeQueuePort) { CFRUNLOOP_WAKEUP_FOR_TIMER();...= MACH_PORT_NULL && livePort == rlm->_timerPort) { CFRUNLOOP_WAKEUP_FOR_TIMER();
处理消息 handle_msg:; if(MACH_PORT_NULL == livePort) { CFRUNLOOP_WAKEUP_FOR_NOTHING...(); } else if(livePort == rl->_wakeUpPort) { CFRUNLOOP_WAKEUP_FOR_WAKEUP();...= MACH_PORT_NULL && livePort == modeQueuePort) { // 处理定时器事件 CFRUNLOOP_WAKEUP_FOR_TIMER...(); } else if(livePort == dispatchPort) { // 处理主线程消息 CFRUNLOOP_WAKEUP_FOR_DISPATCH...(); } else { // 处理 sources1 CFRUNLOOP_WAKEUP_FOR_SOURCE(); }
可以从CF框架源码 的 CFRunLoop.h和CFRunLoop.c,看看 苹果对 CFRunLoopRef 的定义。...CFRunLoopRef是 结构体__CFRunLoop *的重命名,由 typedef struct __CFRunLoop * CFRunLoopRef; 可知; __CFRunLoop 的定义:...struct __CFRunLoop { CFRuntimeBase _base; pthread_mutex_t _lock; /* locked for accessing...timerSoftDeadline; /* TSR */ uint64_t _timerHardDeadline; /* TSR */ }; 看完上面 __CFRunLoopMode 和 __CFRunLoop...else if (msg_is_dispatch) { __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__(msg);
_CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION_(kCFRunloopBeforeSources); _CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK..._CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION_(source0); /// 5....GCD处理main block; _CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__(block); /// 6....如果是被timer唤醒的,回调timer _CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION(timer); ///..._CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__(source1); } while (...); /// 10.
接下来查看一下CFRunLoopRef具体的数据结构如下: struct __CFRunLoop { CFRuntimeBase _base; pthread_mutex_t _lock...RunLoop数据结构 上图很好的描述了struct __CFRunLoop数据结构相关成员变量的关系,每一个__CFRunLoop对象可以包含数个不同的Mode,而每一个Mode又包含了数个Source...中比较重要的几个成员变量: struct __CFRunLoop { ......__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__(kCFRunLoopBeforeSources); __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK...__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__(source0); __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK
无处不在的runloop 我们上图中,调用栈中有一个很长的函数——__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__。...__CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ // 处理timer回调 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0...RunLoop结构 通过上图可以看出: 一个thread对应一个runloop Cocoa层的NSRunLoop是对CF层的CFRunLoop的封装 一个runloop对应多个runLoopMode 一个...RunLoop结构体定义 // RunLoop的结构体定义 struct __CFRunLoop { pthread_mutex_t _lock; //...其中的RCTMessageThread就是C++对CFRunloop的封装。 其他有使用runLoop的地方还有卡顿监控、异步绘制等。
本文转自ibireme的《深入理解RunLoop》 RunLoop 是 iOS 和 OSX 开发中非常基础的一个概念,这篇文章将从 CFRunLoop 的源码入手,介绍 RunLoop 的概念以及底层实现原理...CFRunLoop 是基于 pthread 来管理的。...如果一个 mode 中一个 item 都没有,则 RunLoop 会直接退出,不进入循环 RunLoop 的 Mode CFRunLoopMode 和 CFRunLoop 的结构大致如下: struct...__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__(kCFRunLoopBeforeSources); __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK...__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__(source0); __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK
的callback指针,通知runloop的activity状态变化 __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ // 处理添加到runloop...的block __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ // 处理分发给主线程的事件 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION...__ // 处理timer回调 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ // 处理source0回调 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1...runLoop 结构 runLoop的结构如下图所示: [runloop结构] 通过上图可以看出: 一个thread对应一个runloop Cocoa层的NSRunLoop是对CF层的CFRunLoop...其中的RCTMessageThread就是C++对CFRunloop的封装。 其他有使用runLoop的地方还有卡顿监控、异步绘制等。
--- runLoop是如何实现的 首先要明确的一点事,在平时我们使用的是Foundation框架的NSRunLoop类去做一些实现,而其实NSRunLoop是基于CoreFoundation框架中的CFRunLoop...所以我们这里着重介绍CFRunLoop,毕竟我们能拿到CFRunLoop的源码。...1.runLoop的组成 struct __CFRunLoop { CFRuntimeBase _base; pthread_mutex_t _lock; /* locked...block_item *_blocks_head; struct _block_item *_blocks_tail; CFTypeRef _counterpart; }; 我们大概可以CFRunLoop...= MACH_PORT_NULL && livePort == rlm->_timerPort) {//处理定时器事件 CFRUNLOOP_WAKEUP_FOR_TIMER();
如果找到CFRunloop的源码,我们可以看到,CFRunloop.c的源码也就3900行左右。所以说Runloop其实比Runtime要简单多了!...CFRunloopRef的定义如下: typedef struct CF_BRIDGED_MUTABLE_TYPE(id) __CFRunLoop * CFRunLoopRef; 这说明,CFRunLoopRef...是一个指向__CFRunLoop结构体的指针,__CFRunLoop结构体的定义如下: struct __CFRunLoop { CFRuntimeBase _base; pthread_mutex_t...= MACH_PORT_NULL && livePort == modeQueuePort) { CFRUNLOOP_WAKEUP_FOR_TIMER();...(); } else { CFRUNLOOP_POLL(); } //通过mach_msg发送或者接收的消息都是指针, //如果直接发送或者接收消息体,
#include #include #include <CoreFoundation/CFBag.h...handle_msg 中的代码片段: ...... else if (livePort == dispatchPort) { CFRUNLOOP_WAKEUP_FOR_DISPATCH();...)6, NULL); #if DEPLOYMENT_TARGET_WINDOWS void *msg = 0; #endif // 获取GCDMainQ上的异步任务并执行 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE...static void __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__(void *msg) { _dispatch_main_queue_callback
handle nothing } //被显示唤醒 else if (livePort == rl->_wakeUpPort) { CFRUNLOOP_WAKEUP_FOR_WAKEUP...= MACH_PORT_NULL && livePort == modeQueuePort) { CFRUNLOOP_WAKEUP_FOR_TIMER();...= MACH_PORT_NULL && livePort == rlm->_timerPort) { CFRUNLOOP_WAKEUP_FOR_TIMER();...函数,调用主队列来执行任务,这个任务就在这里处理 */ else if (livePort == dispatchPort) { CFRUNLOOP_WAKEUP_FOR_DISPATCH...didDispatchPortLastTime = true; } //处理source1事件 else { CFRUNLOOP_WAKEUP_FOR_SOURCE
(rl, rlm, mach_absolute_time()) } else if (被 GCD 唤醒) { // 处理 GCD __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE...msg->msgh_size = buffer_size; msg->msgh_id = 0; if (TIMEOUT_INFINITY == timeout) { CFRUNLOOP_SLEEP...(); } else { CFRUNLOOP_POLL(); } // ⚠️⚠️⚠️ ret = mach_msg(msg, MACH_RCV_MSG|(voucherState...voucher_copy(); } else { *voucherCopy = NULL; } } CFRUNLOOP_WAKEUP
我们来看下 CFRunloop 以及 CFRunloopMode的定义: ?...正如上面介绍的,CFRunloopMode 是由几种mode item的集合构成的,而CFRunloop 又包含若干个CFRunloopMode。...CFRunloop中还定义了commonModes 和 commonModeItems 两个集合,这里有个介绍: 可以将一个mode标记为common属性,也就是调用下面这个接口将mode加入到_commonModes...CFRunloop.c 的源码可以在这里https://opensource.apple.com/source/CF/CF-855.17/CFRunLoop.c.auto.html看到,下面是关键部分的源代码
CFRunLoop 是基于 pthread 来管理的。 ...1.4 RunLoop的Mode CFRunLoopMode和CFRunLoop的结构大致如下: struct __CFRunLoopMode { // Mode Name, 例如...else if (msg_is_dispatch) { __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__(msg);...__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__(kCFRunLoopBeforeSources); __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK...__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__(source0); __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK
RunLoop结构体 通过源码我们找到__CFRunLoop结构体 struct __CFRunLoop { CFRuntimeBase _base; pthread_mutex_t _...__CFRunLoopDoObservers 内部调用 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ __CFRunLoopDoBlocks...内部调用 __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ __CFRunLoopDoSources0 内部调用 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0..._PERFORM_FUNCTION__ __CFRunLoopDoTimers 内部调用 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION...__ GCD 调用 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ __CFRunLoopDoSource1 内部调用 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1
__(); static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__(); static void __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE...__(); static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__(); static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0..._PERFORM_FUNCTION__(); static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__(); Observer...__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__() } else { __CFRunLoopDoSource1();...timeout); //通知observers,即将退出runloop __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBERVER_CALLBACK_FUNCTION__(CFRunLoopExit
领取专属 10元无门槛券
手把手带您无忧上云