RunLoop

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.触摸事件

  1. performSelector: onThread:
  • source1

1.基于Port的线程间通信

  1. 系统事件捕捉
  • 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在滑动时停止工作的问题
  • 监控应用卡顿
  • 性能优化

你可能感兴趣的:(RunLoop)