runloop : 程序运行过程中循环做一些事情
1.应用范畴
- 定时器(Timer)、PerformSelector
- GCD Async Main Queue
- 事件响应、手势识别、界面刷新
- 网络请求
- AutoreleasePool
2.作用
- 保持程序的持续运行
- 处理App中的各种事件(触摸事件、定时器事件)
- 节省CPU资源,提高程序性能:该做事做事,该休息休息
3.RunLoop与线程间的关系
- 一对一的关系,线程为key,RunLoop为value,存放在全局映射(CFMutableDictionaryRef)__CFRunLoops中;
- 线程创建完后并没有RunLoop对象,RunLoop在第一次获取它时创建;
- RunLoop会在线程结束时销毁;
- 主线程的RunLoop在程序启动时已经获取(创建),手动创建的子线程默认没有开启RunLoop
- 获取主线程
NSRunLoop *mainRunloop = [NSRunLoop mainRunLoop];
CFRunLoopRef mainRunloop = CFRunLoopGetMain();
- 获取当前线程
NSRunLoop *currentRunloop = [NSRunLoop currentRunLoop];
CFRunLoopRef currentRunloop = CFRunLoopGetCurrent();
4.数据结构
- CFRunLoopRef
typedef struct __CFRunLoop * CFRunLoopRef;
struct __CFRunLoop {
/*
CFRuntimeBase _base;
pthread_mutex_t _lock; // locked for accessing mode list
__CFPort _wakeUpPort; // used for CFRunLoopWakeUp
Boolean _unused;
volatile _per_run_data *_perRunData; // reset for runs of the run loop
*/
pthread_t _pthread;
// uint32_t _winthread;
CFMutableSetRef _commonModes;
CFMutableSetRef _commonModeItems;
CFRunLoopModeRef _currentMode;
CFMutableSetRef _modes;
/*
struct _block_item *_blocks_head;
struct _block_item *_blocks_tail;
CFAbsoluteTime _runTime;
CFAbsoluteTime _sleepTime;
CFTypeRef _counterpart;
*/
};
- CFRunLoopModeRef
typedef struct __CFRunLoopMode *CFRunLoopModeRef;
struct __CFRunLoopMode {
/*
CFRuntimeBase _base;
pthread_mutex_t _lock; // must have the run loop locked before locking this
CFStringRef _name;
Boolean _stopped;
char _padding[3];
*/
CFMutableSetRef _sources0;
CFMutableSetRef _sources1;
CFMutableArrayRef _observers;
CFMutableArrayRef _timers;
/*
CFMutableDictionaryRef _portToV1SourceMap;
__CFPortSet _portSet;
CFIndex _observerMask;
#if USE_DISPATCH_SOURCE_FOR_TIMERS
dispatch_source_t _timerSource;
dispatch_queue_t _queue;
Boolean _timerFired; // set to true by the source when a timer has fired
Boolean _dispatchTimerArmed;
#endif
#if USE_MK_TIMER_TOO
mach_port_t _timerPort;
Boolean _mkTimerArmed;
#endif
#if DEPLOYMENT_TARGET_WINDOWS
DWORD _msgQMask;
void (*_msgPump)(void);
#endif
uint64_t _timerSoftDeadline; /* TSR */
uint64_t _timerHardDeadline; /* TSR */
};
*/
- CFRunLoopObserverRef
typedef struct __CFRunLoopObserver * CFRunLoopObserverRef;
struct __CFRunLoopObserver {
CFRuntimeBase _base;
pthread_mutex_t _lock;
CFRunLoopRef _runLoop;
CFIndex _rlCount;
CFOptionFlags _activities; /* immutable */
CFIndex _order; /* immutable */
CFRunLoopObserverCallBack _callout; /* immutable */
CFRunLoopObserverContext _context; /* immutable, except invalidation */
};
- CFRunLoopTimerRef
typedef struct CF_BRIDGED_MUTABLE_TYPE(NSTimer) __CFRunLoopTimer * CFRunLoopTimerRef;
struct __CFRunLoopTimer {
CFRuntimeBase _base;
uint16_t _bits;
pthread_mutex_t _lock;
CFRunLoopRef _runLoop;
CFMutableSetRef _rlModes;
CFAbsoluteTime _nextFireDate;
CFTimeInterval _interval; /* immutable */
CFTimeInterval _tolerance; /* mutable */
uint64_t _fireTSR; /* TSR units */
CFIndex _order; /* immutable */
CFRunLoopTimerCallBack _callout; /* immutable */
CFRunLoopTimerContext _context; /* immutable, except invalidation */
};
- CFRunLoopSourceRef
typedef struct __CFRunLoopSource * CFRunLoopSourceRef;
struct __CFRunLoopSource {
CFRuntimeBase _base;
uint32_t _bits;
pthread_mutex_t _lock;
CFIndex _order; /* immutable */
CFMutableBagRef _runLoops;
union {
CFRunLoopSourceContext version0; /* immutable, except invalidation */
CFRunLoopSourceContext1 version1; /* immutable, except invalidation */
} _context;
};
5. RunLoop运行逻辑
- source0
1.触摸事件
- performSelector: onThread:
- source1
1.基于Port的线程间通信
- 系统事件捕捉
- observer
1.用于监听RunLoop的状态
2.UI刷新(BeforeWaiting)
3.AutoReleasePool
- timer
1.NSTimer
2.performSelector: withObject: afterDelay:
6.RunLoop状态
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
};
- kCFRunLoopEntry:即将进入RunLoop
- kCFRunLoopBeforeTimers: 即将处理Timer
- kCFRunLoopBeforeSources:即将处理source
- kCFRunLoopBeforeWaiting:即将进入休眠
- kCFRunLoopAfterWaiting:即将从休眠中唤醒
- kCFRunLoopExit:即将退出RunLoop
- kCFRunLoopAllActivities
7. RunLoop执行流程
-
RunLoop流程
runloop1.png -
RunLoop详细流程
runloop2.png
8. RunLoop应用
- 控制线程生命周期(线程保活)
- 解决NSTimer在滑动时停止工作的问题
- 监控应用卡顿
- 性能优化