IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> RunLoop理解(二)数据结构 -> 正文阅读

[移动开发]RunLoop理解(二)数据结构

CFRunLoopRef

RunLoopRef

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

_pthread:RunLoop与线程是一一对应关系

_commonModes:存储着NSString对象的集合(Mode的名称)

_commonModelItems:存储着被标记为通用模式的Sourece0 / Source1 / Timer / Observer

_currentMode: RunLoop 当前的运行模式

_modes:存储着RunLoop所有的Mode(CFRunLoopModeRef)模式

// CFRunLoop.h
typedef struct __CFRunLoop * CFRunLoopRef;
// CFRunLoop.c
struct __CFRunLoop {
    pthread_t _pthread;  // 与线程一一对应
    CFMutableSetRef _commonModes;
    CFMutableSetRef _commonModeItems;
    CFRunLoopModeRef _currentMode;
    CFMutableSetRef _modes;
    ...
};

CFRunLoopModeRef

CFRunLoopModeRef 代表 RunLoop 的运行模式;

一个RunLoop包含若干个Mode,作为currentMode;

RunLoop启动时只能选择其中一个Model,作为currentModel;

如果需要切换Mode,只能退出当前Loop,再重新选择一个Mode进入,切换模式不会导致程序退出;

不同Model中的Source0 / Source1/ Timer / Observer 能分隔开来,互不影响;

如果Mode里没有任何Source0 / Source1 / Timer / Observer ,RunLoop会立马退出。

// CFRunLoop.h
typedef struct __CFRunLoopMode *CFRunLoopModeRef;
// CFRunLoop.c
struct __CFRunLoopMode {
    CFStringRef _name;             // mode 类型,如:NSDefaultRunLoopMode
    CFMutableSetRef _sources0;     // CFRunLoopSourceRef
    CFMutableSetRef _sources1;     // CFRunLoopSourceRef
    CFMutableArrayRef _observers;  // CFRunLoopObserverRef
    CFMutableArrayRef _timers;     // CFRunLoopTimerRef
    ...
};

RunLoop 的常见模式

ModeName描述
NSDefaultRunLoopMode / KCFRunLoopDefaultMode默认模式
UITrackingRunLoopMode界面追踪模式,用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他 Mode 影响;
NSRunLoopCommonModes / KCFRunLoopCommonModes通用模式(默认包含 KCFRunLoopDefaultMode 和 UITrackingRunLoopMode)该模式不是实际存在的一种模式,它只是一个特殊的标记,是同步Source0/Source1/Timer/Observer到多个 Mode 中的技术方案。被标记为通用模式的Source0/Source1/Timer/Observer都会存放到 _commonModeItems 集合中,会同步这些Source0/Source1/Timer/Observer到多个 Mode 中。

备注:

  • NSDefaultRunLoopModeNSRunLoopCommonModes属于Foundation框架;
  • KCFRunLoopDefaultModeKCFRunLoopCommonModes属于Core Foundation框架;
  • 前者是对后者的封装,作用相同。

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

Mode做到了屏蔽的效果,当RunLoop运行在Mode1下面的时候,是处理不了Mode2的事件的;

比如NSDefaultRunLoopMode默认模式和UITrackingRunLoopMode滚动模式,滚动屏幕的时候就会切换到滚动模式,就不用去处理默认模式下的事件了,保证了UITableView等的滚动顺畅。

CFRunLoopSourceRef

在RunLoop中有两个很重要的概念,一个是上面提到的模式,还有一个就是事件源。事件源分为输入源(Input Sources)和定时器源(Timer Sources)两种;

输入源(Input Sources)又分为Source0和Source1两种,以下__CFRunLoopSources中的共用体union中的version0和version1就分别对应Source0和Source1。

// CFRunLoop.h
typedef struct __CFRunLoopSource * CFRunLoopSourceRef;
// CFRunLoop.m
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;
};

Source0 和 Source1 的区别:

Input Sources区别
Source0需要手动唤醒线程:添加Source0到RunLoop并不会主动唤醒线程,需要手动唤醒)① 触摸事件处理② performSelector:onThread:
Source1具备唤醒线程的能力① 基于 Port 的线程间通信② 系统事件捕捉:系统事件捕捉是由Source1来处理,然后再交给Source0处理

CFRunLoopTimerRef

  • CFRunloopTimerNSTimer是 toll-free bridged 的,可以相互转换;
  • performSelector:withObject:afterDelay:方法会创建timer并添加到RunLoop中。
// CFRunLoop.h
typedef struct CF_BRIDGED_MUTABLE_TYPE(NSTimer) __CFRunLoopTimer * CFRunLoopTimerRef;
// CFRunLoop.c
struct __CFRunLoopTimer {
    CFRuntimeBase _base;
    uint16_t _bits;
    pthread_mutex_t _lock;
    CFRunLoopRef _runLoop;           // 添加该 timer 的 RunLoop
    CFMutableSetRef _rlModes;        // 所有包含该 timer 的 modeName
    CFAbsoluteTime _nextFireDate;
    CFTimeInterval _interval;        /* immutable 理想时间间隔 */    
    CFTimeInterval _tolerance;       /* mutable 时间偏差 */  
    uint64_t _fireTSR;               /* TSR units */
    CFIndex _order;                  /* immutable */
    CFRunLoopTimerCallBack _callout; /* immutable 回调入口 */
    CFRunLoopTimerContext _context;  /* immutable, except invalidation */
};

CFRunLoopObserverRef

作用

  • CFRunLoopObserverRef用来监听RunLoop的 6 种活动状态
/* Run Loop Observer Activities */
typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
    kCFRunLoopEntry = (1UL << 0),          // 即将进入 RunLoop
    kCFRunLoopBeforeTimers = (1UL << 1),   // 即将处理 Timers
    kCFRunLoopBeforeSources = (1UL << 2),  // 即将处理 Sources
    kCFRunLoopBeforeWaiting = (1UL << 5),  // 即将进入休眠
    kCFRunLoopAfterWaiting = (1UL << 6),   // 刚从休眠中唤醒
    kCFRunLoopExit = (1UL << 7),           // 即将退出 RunLoop
    kCFRunLoopAllActivities = 0x0FFFFFFFU  // 表示以上所有状态
};
  • UI 刷新(BeforeWaiting)
  • Autorelease pool(BeforeWaiting)

定义

// CFRunLoop.h
typedef struct __CFRunLoopObserver * CFRunLoopObserverRef;
// CFRunLoop.c
struct __CFRunLoopObserver {
    CFRuntimeBase _base;
    pthread_mutex_t _lock;
    CFRunLoopRef _runLoop;              // 添加该 observer 的 RunLoop
    CFIndex _rlCount;
    CFOptionFlags _activities;          /* immutable 监听的活动状态 */
    CFIndex _order;                     /* immutable */
    CFRunLoopObserverCallBack _callout; /* immutable 回调入口 */
    CFRunLoopObserverContext _context;  /* immutable, except invalidation */
};

CFRunLoopObserverRef中的_activities用来保存RunLoop的活动状态。当RunLoop的状态发生改变时,通过回调_callout通知所有监听这个状态的Observer

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-12-28 23:02:56  更:2021-12-28 23:03:34 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:20:04-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码