NSThread 创建

- (instancetype)init {
    self = [super init];
    if (self) {
        _NSThreadData *threadData = [_NSThreadData new];
        // fold some step of initialize threadData
        pthread_attr_init(threadData->attr);
        pthread_attr_setscope(threadData->attr, 1);
        pthread_attr_setdetachstate(threadData->attr, 2);
        // intialize thread id
        threadData->tid = 0x0;
        self->_private = threadData;
        if (pthread_attr_getschedparam(threadData->attr, -40) == 0x0) {
           //... do something
        }
        threadData->pri = threadData->defpri;

    }
    return self;
}

NSThread currentThread 获取当前线程


+ (NSThread *)currentThread {
    if ( !*__NSIsMultiThreaded && (pthread_main_np() == 0x0)) {
        *__NSIsMultiThreaded = YES;
        [[NSNotificationCenter _defaultCenterWithoutCreating] postNotificationName:@"NSWillBecomeMultiThreadedNotification"
                                                                            object:nil userInfo:nil];
    }
    // obtain ID of the calling thread
    pthread_t pthread = pthread_self();
    /**
     * __NSThreadGet0(arg, arg)
     * 内部实现 发现pthread token 为 0x0 会取 主线程 thread_t
     * 然后会优先取缓存
     * 然后是构造并持有新的NSThread实例,
     * 内部使用pthread_mutex_lock保证线程安全
     */
    NSThread *thread = __NSThreadGet0(pthread, nil); // nil =  cmd
    return thread;
}

也即是我们获取到某个线程的NSThread对象是lazy load的,所有iOS设备的线程实现都是pthread,NSThead是对低层级pthread实现的线程,以及数据的封装暴露出来的外观。

NSThread start


- (void)start {

    if (self->_private->status >= 0xd) {

        @throw [NSException exceptionWithName:@"NSInvalidArgumentException" reason:@"%@: attempt to start the thread again" userInfo:nil];
    }
    self->_private->status = 0xd;
    if (self->_private->cancel != 0x0) {
        self->_private->status = 0xf;
    }
    else {
        if (*__NSIsMultiThreaded == 0x0) {
            *__NSIsMultiThreaded = 0x1;
            [[NSNotificationCenter defaultCenter] postNotificationName:@"NSWillBecomeMultiThreadedNotification"
                                                                                object:nil userInfo:nil];
        }
        if (self->_private->qos != 0x0) {
            pthread_attr_set_qos_class_np(self->_private->_attr);
        }
        /**
         * ___NSThread__start__
         * 1.获取performQ中等待执行的performSelector任务
         * 2.创建对应的source 立即执行得(input source) 和稍后执行的 (timer source)
         * 3. wakeUpLoop
         * 
         * 1.创建AutoReleasePool Push
         * 2.执行thread 的 main函数
         * 3.AutoReleasePool Pop
         * 
         */
        int res = pthread_create(self->_private->_tid, self->_private->_attr, ___NSThread__start__, [self retain]);
        if (res != 0) {
            NSLog(@"Thread creation failed with error ");
        }
    }
    return;
}


所以performSelector的实现是依赖runloop的,并且需要手动启用对应线程的runloop,才能保证performSelector在某个线程中成功。

另外,主线程的创建实现并不在NSThread中,包括主线程的loop设置,通过[NSThread currentThread] 获取到的NSThread只是根据以及存在的main pthread以及数据,创建的包装实例。后续附上App启动过程的main thread初始化。