美文网首页
RunLoop部分

RunLoop部分

作者: SeanLink | 来源:发表于2021-11-16 10:32 被阅读0次

--------------------RunLoop--------------------

什么是RunLoop

运行循环,在程序运行过程中循环做一些事情

RunLoopde 应用范畴

定时器(Timer)、PerformSelector
GCD Async Main Queue
事件响应、手势识别、界面刷新
网络请求
AutoreleasePool

RunLoop与线程

  1. 每条线程都有唯一的一个与之对应的RunLoop对象
  2. RunLoop保存在一个全局的Dictionary里,线程作为key,RunLoop作为value
  3. 线程刚创建时并没有RunLoop对象,RunLoop会在第一次获取它时创建
  4. RunLoop会在线程结束时销毁
  5. 主线程的RunLoop已经自动获取(创建),子线程默认没有开启RunLoop

获得RunLoop对象

Foundation
[NSRunLoop currentRunLoop]; // 获得当前线程的RunLoop对象
[NSRunLoop mainRunLoop]; // 获得主线程的RunLoop对象

Core Foundation
CFRunLoopGetCurrent(); // 获得当前线程的RunLoop对象
CFRunLoopGetMain(); // 获得主线程的RunLoop对象

RunLoop相关的5个类:
CFRunLoopRef
CFRunLoopModeRef
CFRunLoopSourceRef
CFRunLoopTimerRef
CFRunLoopObserverRef

CFRunLoop和 CFRunLoopMode

// CFRunLoop.h
typedef struct __CFRunLoop * CFRunLoopRef;
// CFRunLoop.c
struct __CFRunLoop {
    pthread_t _pthread;  // 与线程一一对应
    CFMutableSetRef _commonModes;
    CFMutableSetRef _commonModeItems;
    CFRunLoopModeRef _currentMode;
    CFMutableSetRef _modes;
    ...
};
// 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
    ...
};

CFRunLoopModeRef

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

常见的两种mode:

  • kCFRunLoopDefaultMode(NSDefaultRunLoopMode):App的默认Mode,通常主线程是在这个Mode下运行
  • UITrackingRunLoopMode:界面跟踪 Mode,用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他 Mode 影响

CFRunLoopObserverRef

/* 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  // 表示以上所有状态
};

添加RunLoop的监听:

// 创建Observer
CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(kCFAllocatorDefault, kCFRunLoopAllActivities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
    switch (activity) {
        case kCFRunLoopEntry: {
            NSLog(@"kCFRunLoopEntry");
            break;
        }
        case kCFRunLoopBeforeTimers: {
            NSLog(@"kCFRunLoopEntry");
        } break;
        case kCFRunLoopBeforeSources: {
            NSLog(@"kCFRunLoopEntry");
        } break;
        case kCFRunLoopBeforeWaiting: {
            NSLog(@"kCFRunLoopEntry");
        } break;
        case kCFRunLoopAfterWaiting: {
            NSLog(@"kCFRunLoopEntry");
        } break;
        case kCFRunLoopExit: {
            NSLog(@"kCFRunLoopExit");
            break;
        }
        default:
            break;
    }
});
// 添加Observer到RunLoop中
CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer, kCFRunLoopCommonModes);
// 释放
CFRelease(observer);

RunLoop的运行逻辑

先上一张老图


image.png
  • Source0
    触摸事件处理
    performSelector:onThread:

  • Source1
    基于Port的线程间通信
    系统事件捕捉

  • Timers
    NSTimer
    performSelector:withObject:afterDelay:

  • Observers
    用于监听RunLoop的状态
    UI刷新(BeforeWaiting)
    Autorelease pool(BeforeWaiting)

过程:


image.png

相关文章

  • RunLoop部分

    --------------------RunLoop-------------------- 什么是RunLoo...

  • iOS Runtime

    iOS RunLoop详解---重要而详细iOS RunLoop详解-部分

  • 记录一些介绍Runloop的牛文

    老司机出品——源码解析之RunLoop详解深入理解RunLoop关于RunLoop部分源码的注释CFRunLoop...

  • 深入浅出 RunLoop

    前言 文章主要分为四个部分 一、RunLoop 简介 二、RunLoop 相关接口 三、RunLoop 相关逻辑流...

  • RunLoop(基础部分)

    在很多地方,都能看到这个概念,却不知道到底是个什么玩意,网上写的也很抽象,理解起来很吃力,官方文档官方文档也只是泛...

  • iOS-RunLoop究竟是怎么运作的

    RunLoop简介(Introduction) RunLoop是线程基础架构的一部分。RunLoop存在的目的是让...

  • RunLoop

    RunLoop是什么 字面意思运行循环 RunLoop是线程的基础架构部分RunLoop的目的,就是使得线程在有任...

  • iOS - Runloop

    Runloop —.基础知识部分 1.什么是Runloop? 答:RunLoop的实质是一个死循环(do-whil...

  • Timer和Runloop

    1、runloop是什么? runloop是事件接收和分发机制的一种实现。 runloop是线程的基础组成部分,一...

  • RunLoop 和线程

    RunLoop 和 线程的关系 (基本理解) RunLoop 是线程的基础架构部分,Cocoa和CoreFund...

网友评论

      本文标题:RunLoop部分

      本文链接:https://www.haomeiwen.com/subject/njqhtrtx.html