美文网首页
iOS 线程与RunLoop的关系

iOS 线程与RunLoop的关系

作者: 会飞的超大鱼 | 来源:发表于2019-06-28 13:47 被阅读0次

代码笔记、知识扩展

iOS 开发中能遇到两个线程对象: pthread_t 和 NSThread。过去苹果有份文档标明了 NSThread 只是 pthread_t 的封装,但那份文档已经失效了,现在它们也有可能都是直接包装自最底层的 mach thread。苹果并没有提供这两个对象相互转换的接口,但不管怎么样,可以肯定的是 pthread_t 和 NSThread 是一一对应的。比如,你可以通过 pthread_main_thread_np() 或 [NSThread mainThread] 来获取主线程;也可以通过 pthread_self() 或 [NSThread currentThread] 来获取当前线程。CFRunLoop 是基于 pthread 来管理的。

苹果不允许直接创建 RunLoop,它只提供了两个自动获取的函数:CFRunLoopGetMain() 和 CFRunLoopGetCurrent()。 这两个函数内部的逻辑大概是下面这样:

/// 全局的Dictionary,key 是 pthread_t, value 是 CFRunLoopRef
static CFMutableDictionaryRef loopsDic;
/// 访问 loopsDic 时的锁
static CFSpinLock_t loopsLock;
 
/// 获取一个 pthread 对应的 RunLoop。
CFRunLoopRef _CFRunLoopGet(pthread_t thread) {
    OSSpinLockLock(&loopsLock);
    
    if (!loopsDic) {
        // 第一次进入时,初始化全局Dic,并先为主线程创建一个 RunLoop。
        loopsDic = CFDictionaryCreateMutable();
        CFRunLoopRef mainLoop = _CFRunLoopCreate();
        CFDictionarySetValue(loopsDic, pthread_main_thread_np(), mainLoop);
    }
    
    /// 直接从 Dictionary 里获取。
    CFRunLoopRef loop = CFDictionaryGetValue(loopsDic, thread));
    
    if (!loop) {
        /// 取不到时,创建一个
        loop = _CFRunLoopCreate();
        CFDictionarySetValue(loopsDic, thread, loop);
        /// 注册一个回调,当线程销毁时,顺便也销毁其对应的 RunLoop。
        _CFSetTSD(..., thread, loop, __CFFinalizeRunLoop);
    }
    
    OSSpinLockUnLock(&loopsLock);
    return loop;
}
 
CFRunLoopRef CFRunLoopGetMain() {
    return _CFRunLoopGet(pthread_main_thread_np());
}
 
CFRunLoopRef CFRunLoopGetCurrent() {
    return _CFRunLoopGet(pthread_self());
}

综上所述,线程和 RunLoop 之间是一一对应的,其关系是保存在一个全局的 Dictionary 里。线程刚创建时并没有 RunLoop,如果你不主动获取,那它一直都不会有。RunLoop 的创建是发生在第一次获取时,RunLoop 的销毁是发生在线程结束时。你只能在一个线程的内部获取其 RunLoop(主线程除外)。

节选自 https://blog.ibireme.com/2015/05/18/runloop/

相关文章

  • RunLoop

    iOS刨根问底-深入理解RunLoop runloop 和线程有什么关系 iOS 多线程:RunLoop详细总结

  • iOS 架构师 面试记录

    面试某与联网大厂 iOS 架构师 1、什么是Runloop 、线程与Runloop的区别(或者说关系)Runloo...

  • Runloop相关探索

    Runloop 和 线程 在CFRunloop中已经说明了一个线程及其runloop的对应关系,现在以iOS中NS...

  • runloop

    runloop是什么 runloop与线程有什么关系 runloop的原理 runloop的使用

  • RunLoop与线程

    RunLoop与线程之间的关系 每条线程都有唯一一个与之对应的RunLoop对象主线程的RunLoop已经自动创建...

  • 深入理解Runloop

    RunLoop 的概念 RunLoop 与线程的关系 RunLoop 对外的接口 RunLoop 的 Mode R...

  • Autorelease 对象的内存管理

    AutoreleasePool 与Runloop 关系 主线程默认会开启Runloop, Runloop 会自动帮...

  • RunLoop初探,满足项目的基本应用

    iOS开发肯定离不开多线程编程,而多线程又跟RunLoop有着密切的关系,这篇文章就来解剖下RunLoop。 每个...

  • 深入理解RunLoop

    转载:ibireme RunLoop 与线程的关系 RunLoop 对外的接口 RunLoop 的 Mode Ru...

  • RunLoop

    一、获取RunLoop 二、RunLoop与线程关系1、每条线程都有唯一的一个与之对应的RunLoop对象2、Ru...

网友评论

      本文标题:iOS 线程与RunLoop的关系

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