iOS 底层学习方向、面试总结

iOS 涨薪: Run Loop 面试题

2020-11-04  本文已影响0人  编程怪才_凌雨画

Run Loop

运行循环

app 程序只有不停地运行, 才能不断响应用户的操作

Run Loop 两大功能:

从睡眠中 -> 处理消息, 需要一个唤醒的过程

1、 讲讲 RunLoop, 项目中有用到吗?

RunLoop 的基本作用:

保持程序的持续运行

节省 CPU 的资源,提高程序的性能 ( 没有事情,就请休眠,不要功耗。有事情,就处理)

2、 RunLoop 内部实现逻辑?

struct __CFRunLoop {
    CFRuntimeBase _base;
    pthread_mutex_t _lock;            /* locked for accessing mode list */
    __CFPort _wakeUpPort;            // used for CFRunLoopWakeUp 
    Boolean _unused;
    volatile _per_run_data *_perRunData;              // reset for runs of the run loop
    
    
    
    pthread_t _pthread;
    uint32_t _winthread;
    
    
    
    CFMutableSetRef _commonModes;
    CFMutableSetRef _commonModeItems;
    CFRunLoopModeRef _currentMode;
    CFMutableSetRef _modes;
    struct _block_item *_blocks_head;
    struct _block_item *_blocks_tail;
    CFAbsoluteTime _runTime;
    CFAbsoluteTime _sleepTime;
    CFTypeRef _counterpart;
};

在此一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这有个iOS交流群:642363427,不管你是小白还是大牛欢迎入驻 ,分享BAT,阿里面试题、面试经验,讨论技术!

3、 RunLoop 和线程的关系?

子线程,要什么 runloop?

没有 runloop , 就是命令行,调用一次就完结

有了 runloop, 可以反复休眠、唤醒、处理消息

CFRunLoopRef CFRunLoopGetCurrent(void) {
    CHECK_FOR_FORK();
    CFRunLoopRef rl = (CFRunLoopRef)_CFGetTSD(__CFTSDKeyRunLoop);
    if (rl) return rl;
    
    // 从这里拿
    return _CFRunLoopGet0(pthread_self());
}

进入详情

// should only be called by Foundation
// t==0 is a synonym for "main thread" that always works
CF_EXPORT CFRunLoopRef _CFRunLoopGet0(pthread_t t) {
    if (pthread_equal(t, kNilPthreadT)) {
    t = pthread_main_thread_np();
    }
    __CFLock(&loopsLock);
    if (!__CFRunLoops) {
        __CFUnlock(&loopsLock);
    CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, NULL, &kCFTypeDictionaryValueCallBacks);
    CFRunLoopRef mainLoop = __CFRunLoopCreate(pthread_main_thread_np());
    CFDictionarySetValue(dict, pthreadPointer(pthread_main_thread_np()), mainLoop);
    if (!OSAtomicCompareAndSwapPtrBarrier(NULL, dict, (void * volatile *)&__CFRunLoops)) {
        CFRelease(dict);
    }
    CFRelease(mainLoop);
        __CFLock(&loopsLock);
    }
    CFRunLoopRef loop = (CFRunLoopRef)CFDictionaryGetValue(__CFRunLoops, pthreadPointer(t));
    __CFUnlock(&loopsLock);
    if (!loop) {
    CFRunLoopRef newLoop = __CFRunLoopCreate(t);
        __CFLock(&loopsLock);
        
        
     // 从字典里面,获取 runloop 对象
    // __CFRunLoops 字典
    // pthreadPointer(t) ,键 key
    
    
    loop = (CFRunLoopRef)CFDictionaryGetValue(__CFRunLoops, pthreadPointer(t));
    
    // runloop 对象 loop 不存在,就新建
    if (!loop) {
            // 字典中,设置
            //   __CFRunLoops  字典
            //   pthreadPointer(t),键 key
            //   newLoop, 值  value
        CFDictionarySetValue(__CFRunLoops, pthreadPointer(t), newLoop);
        loop = newLoop;
    }
        // don't release run loops inside the loopsLock, because CFRunLoopDeallocate may end up taking it
        __CFUnlock(&loopsLock);
    CFRelease(newLoop);
    }
    if (pthread_equal(t, pthread_self())) {
        _CFSetTSD(__CFTSDKeyRunLoop, (void *)loop, NULL);
        if (0 == _CFGetTSD(__CFTSDKeyRunLoopCntr)) {
            _CFSetTSD(__CFTSDKeyRunLoopCntr, (void *)(PTHREAD_DESTRUCTOR_ITERATIONS-1), (void (*)(void *))__CFFinalizeRunLoop);
        }
    }
    return loop;
}

4、 timer 和 runloop 的关系?

5、 程序中添加每 3 秒响应一次的 NSTimer, 当拖动 tableView 时 timer 可能无法响应,要怎么解决?

6、 RunLoop 是怎么响应用户操作的,具体流程是什么样的?

7、 说说 RunLoop 的几种状态

8、 runloop 的 mode 作用是什么?

推荐👇:

如果你想一起进阶,不妨添加一下交流群642363427

上一篇 下一篇

猜你喜欢

热点阅读