Swift教程

深入浅出 RunLoop(二):数据结构

本文主要是介绍深入浅出 RunLoop(二):数据结构,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

RunLoop 系列文章

深入浅出 RunLoop(一):初识
深入浅出 RunLoop(二):数据结构
深入浅出 RunLoop(三):事件循环机制
深入浅出 RunLoop(四):RunLoop 与线程
深入浅出 RunLoop(五):RunLoop 与 NSTimer
深入浅出 RunLoop(六):相关面试题

CFRunLoopRef

RunLoop对象的底层就是一个CFRunLoopRef结构体,它里面存储着:

  • _pthread:RunLoop与线程是一一对应关系
  • _commonModes:存储着 NSString 对象的集合(Mode 的名称)
  • _commonModeItems:存储着被标记为通用模式的Source0/Source1/Timer/Observer
  • _currentMode:RunLoop当前的运行模式
  • _modes:存储着RunLoop所有的 Mode(CFRunLoopModeRef)模式
typedef struct __CFRunLoop * CFRunLoopRef;

struct __CFRunLoop {
    pthread_t _pthread;  // 与线程一一对应
    CFMutableSetRef _commonModes;
    CFMutableSetRef _commonModeItems;
    CFRunLoopModeRef _currentMode;
    CFMutableSetRef _modes;
    ...
};
复制代码

CFRunLoopModeRef

  • CFRunLoopModeRef代表RunLoop的运行模式;
  • 一个RunLoop包含若干个 Mode,每个 Mode 又包含若干个Source0/Source1/Timer/Observer
  • RunLoop启动时只能选择其中一个 Mode,作为 currentMode;
  • 如果需要切换 Mode,只能退出当前 Loop,再重新选择一个 Mode 进入,切换模式不会导致程序退出;
  • 不同 Mode 中的Source0/Source1/Timer/Observer能分隔开来,互不影响;
  • 如果 Mode 里没有任何Source0/Source1/Timer/ObserverRunLoop会立马退出。
typedef struct __CFRunLoopMode *CFRunLoopModeRef;

struct __CFRunLoopMode {
    CFStringRef _name;             // mode 类型,如:NSDefaultRunLoopMode
    CFMutableSetRef _sources0;     // CFRunLoopSourceRef
    CFMutableSetRef _sources1;     // CFRunLoopSourceRef
    CFMutableArrayRef _observers;  // CFRunLoopObserverRef
    CFMutableArrayRef _timers;     // CFRunLoopTimerRef
    ...
};
复制代码

RunLoop 的常见模式

ModeName 描述
KCFRunLoopDefaultMode / NSDefaultRunLoopMode 默认模式
UITrackingRunLoopMode 界面追踪模式,用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他 Mode 影响;
KCFRunLoopCommonModes / NSRunLoopCommonModes 通用模式(默认包含 KCFRunLoopDefaultMode 和 UITrackingRunLoopMode)

该模式不是实际存在的一种模式,它只是一个特殊的标记,是同步Source0/Source1/Timer/Observer到多个 Mode 中的技术方案。被标记为通用模式的Source0/Source1/Timer/Observer都会存放到 _commonModeItems 集合中,会同步这些Source0/Source1/Timer/Observer到多个 Mode 中。

CFRunLoopModeRef 这样设计有什么好处?Runloop为什么会有多个 Mode?

  • Mode 做到了屏蔽的效果,当RunLoop运行在 Mode1 下面的时候,是处理不了 Mode2 的事件的;
  • 比如NSDefaultRunLoopMode默认模式和UITrackingRunLoopMode滚动模式,滚动屏幕的时候就会切换到滚动模式,就不用去处理默认模式下的事件了,保证了 UITableView 等的滚动顺畅。

CFRunLoopSourceRef

  • Source0:(需要手动唤醒线程
    这篇关于深入浅出 RunLoop(二):数据结构的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!