美文网首页
RunLoop补充知识

RunLoop补充知识

作者: 测试开发雨辰 | 来源:发表于2019-04-16 16:42 被阅读0次
    RunLoop知识合集如下图:
    RunLoop.png
    CFRunLoop简化后的代码分析
    static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInterval seconds, Boolean stopAfterHandle, CFRunLoopModeRef previousMode) {
        
        Boolean didDispatchPortLastTime = true;
        int32_t retVal = 0;
        do {
            
            //通知Observers:即将处理Timers
            __CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeTimers);
            //通知Observers:即将处理Sources
            __CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeSources);
            //处理Blocks
            __CFRunLoopDoBlocks(rl, rlm);
            
            //处理Sources0
            __CFRunLoopDoSources0(rl, rlm, stopAfterHandle);
            if (sourceHandledThisLoop) {
                //有可能再次处理Blocks
                __CFRunLoopDoBlocks(rl, rlm);
            }
            
            //判断是否有sources1,就跳转到handle_msg标记处
            if (__CFRunLoopServiceMachPort(dispatchPort, &msg, sizeof(msg_buffer), &livePort, 0, &voucherState, NULL)) {
                goto handle_msg;
            }
    
            //通知Observers:即将进入休眠
            __CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeWaiting);
            
            //进入休眠,等待其他消息唤醒
            __CFRunLoopSetSleeping(rl);
            __CFPortSetInsert(dispatchPort, waitSet);
            do {
               
                __CFRunLoopServiceMachPort(waitSet, &msg, sizeof(msg_buffer), &livePort, poll ? 0 : TIMEOUT_INFINITY, &voucherState, &voucherCopy);
            } while (1);
            
            if (kCFUseCollectableAllocator) {
                // objc_clear_stack(0);
                // <rdar://problem/16393959>
                memset(msg_buffer, 0, sizeof(msg_buffer));
            }
          
            //醒来
            __CFPortSetRemove(dispatchPort, waitSet);
            __CFRunLoopUnsetSleeping(rl);
            
            //通知Observers:已经唤醒
           __CFRunLoopDoObservers(rl, rlm, kCFRunLoopAfterWaiting);
            
        handle_msg: //看看是谁唤醒了RunLoop,进行相应的处理
    
            if (被timer唤醒的) {
             //处理Timer
              CFRunLoopDoTimers(rl, rlm, mach_absolute_time()))
            }
            else if (被GCD唤醒的) {
                __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__(msg);
            } else {
                //被source1唤醒的
                sourceHandledThisLoop = __CFRunLoopDoSource1(rl, rlm, rls, msg, msg->msgh_size, &reply);
            }
    
            //执行Blocks
            __CFRunLoopDoBlocks(rl, rlm);
            
            //根据之前的执行结果,来决定怎么做
            if (sourceHandledThisLoop && stopAfterHandle) {
                retVal = kCFRunLoopRunHandledSource;
            } else if (timeout_context->termTSR < mach_absolute_time()) {
                retVal = kCFRunLoopRunTimedOut;
            } else if (__CFRunLoopIsStopped(rl)) {
                __CFRunLoopUnsetStopped(rl);
                retVal = kCFRunLoopRunStopped;
            } else if (rlm->_stopped) {
                rlm->_stopped = false;
                retVal = kCFRunLoopRunStopped;
            } else if (__CFRunLoopModeIsEmpty(rl, rlm, previousMode)) {
                retVal = kCFRunLoopRunFinished;
            }
            
            voucher_mach_msg_revert(voucherState);
            os_release(voucherCopy);
            
        } while (0 == retVal);
        
        return retVal;
    }
    
    
    
    SInt32 CFRunLoopRunSpecific(CFRunLoopRef rl, CFStringRef modeName, CFTimeInterval seconds, Boolean returnAfterSourceHandled) {     /* DOES CALLOUT */
        
        //通知Observer:进入Loop
        __CFRunLoopDoObservers(rl, currentMode, kCFRunLoopEntry);
        
        //核心的Loop逻辑
        __CFRunLoopRun(rl, currentMode, seconds, returnAfterSourceHandled, previousMode);
        
        //通知Observer:退出Loop
        __CFRunLoopDoObservers(rl, currentMode, kCFRunLoopExit);
        
        return result;
    }
    
    
    
    void CFRunLoopRun(void) {    /* DOES CALLOUT */
        int32_t result;
        do {
            result = CFRunLoopRunSpecific(CFRunLoopGetCurrent(), kCFRunLoopDefaultMode, 1.0e10, false);
            CHECK_FOR_FORK();
        } while (kCFRunLoopRunStopped != result && kCFRunLoopRunFinished != result);
    }
    

    相关文章

      网友评论

          本文标题:RunLoop补充知识

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