美文网首页
runloop底层源码探究一(runloop的创建)

runloop底层源码探究一(runloop的创建)

作者: iOS劝退师 | 来源:发表于2021-01-08 15:51 被阅读0次

    一、创建runloop

    1、子线程默认不创建runloop,主动获取的时候才去创建(或直接从__CFTSDTable中取)runloop

    [NSRunLoop currentRunLoop]
    //底层源码
    //主线程runloop
    CFRunLoopRef CFRunLoopGetMain(void) {
        CHECK_FOR_FORK();
        static CFRunLoopRef __main = NULL; // no retain needed
    //没有mainrunloop就创建
        if (!__main) __main = _CFRunLoopGet0(pthread_main_thread_np()); // no CAS needed
        return __main;
    }
    //其他线程runloop
    CFRunLoopRef CFRunLoopGetCurrent(void) {
        CHECK_FOR_FORK();
        // 从一个 -》 runLoop
        CFRunLoopRef rl = (CFRunLoopRef)_CFGetTSD(__CFTSDKeyRunLoop);
        if (rl) return rl;
        // 创建一个
        return _CFRunLoopGet0(pthread_self());
    }
    

    流程我画了个图:
    1、首先会从__CFTSDTable找,是否有可用的runloop
    2、如过有就直接将可用的return,如果没有就调用下面这个方法创建一个新的,创建成功后,还是回存到__CFTSDTable中,然后再return

    _CFRunLoopGet0(pthread_self())
    

    __CFTSDTable的定义:
    其中的data[CF_TSD_MAX_SLOTS]应该就是存放runloop的数组

    // Data structure to hold TSD data, cleanup functions for each
    typedef struct __CFTSDTable {
        uint32_t destructorCount;
        uintptr_t data[CF_TSD_MAX_SLOTS];
        tsdDestructor destructors[CF_TSD_MAX_SLOTS];
    } __CFTSDTable;
    //最大存入个数是70个,看注释超过70个会crash
    // If slot >= CF_TSD_MAX_SLOTS, the SPI functions will crash at NULL + slot address.
    // If thread data has been torn down, these functions should crash on CF_TSD_BAD_PTR + slot address.
    #define CF_TSD_MAX_SLOTS 70
    
    other loop获取流程图.png

    相关文章

      网友评论

          本文标题:runloop底层源码探究一(runloop的创建)

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