美文网首页
12.runloop问题

12.runloop问题

作者: ProfessorFan | 来源:发表于2022-05-22 07:06 被阅读0次

    问题

    1.个人对runloop的理解
    2.runloop 运行逻辑
    3.监听runloop 的模式
    4.获取当前子线程中的runloop 整么做
    5.mainRunloop 和 CFRunloopGetMain() 有什么不一样

    答案

    1.个人对runloop的理解

    1.runloop 在我们IOS程序中一直存在,只要app 不死就一直存在(里面相当于一个do-while一直在那里运行等待监听做事情)
    2.一个IOS程序最起码有一个 runloop (也就是mainRunloop).
    3.每一个线程对应一个 runloop
    4.一个runloop 某一时刻只能有一个model
    5.Runloop Model 实际上是 source ,Timer,Observer 的集合,不同的model 把不同组的 source,timer,observer隔绝起来,runloop在某一时刻只能跑在一个model下,处理这一个model 当中的 source ,timer,observer.
    6.apple 文档中提到的五个model,分别是

    NSDefaultRunLoopMode //默认的mode,正常情况下都是在这个mode
    NSConnectionReplyMode
    NSModalPanelRunLoopMode
    NSEventTrackingRunLoopMode //使用这个Mode去跟踪来自用户交互的事件(比如UITableView上下滑动)
    NSRunLoopCommonModes // 这个model 是 (NSEventTrackingRunLoopMode,NSDefaultRunLoopMode)集合
    

    6.Runloop Model 里面结构的作用.
    source: 可以唤醒Runloop 的一些事件,比如用户点击了屏幕,source0 :非系统事件,source1:系统事件
    Timer: 我们经常使用的NSTimer 也就属于这一类
    Observer: 可以用来经停Runloop 的状态变化,并做出反应

    2.runloop 运行逻辑

    runloop运行逻辑.png
    runloop.png

    3.监听runloop 的模式

    1.方式一(通过C语言方式)

       // kCFRunLoopCommonModes默认包括kCFRunLoopDefaultMode、UITrackingRunLoopMode
        // 创建Observer
        CFRunLoopObserverRef observer = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopAllActivities, YES, 0, observeRunLoopActicities, NULL);
    //    // 添加Observer到RunLoop中
        CFRunLoopAddObserver(CFRunLoopGetMain(), observer, kCFRunLoopCommonModes);
    //    // 释放
        CFRelease(observer);
    
    void observeRunLoopActicities(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info)
    {
        switch (activity) {
            case kCFRunLoopEntry:
                NSLog(@"kCFRunLoopEntry");
                break;
            case kCFRunLoopBeforeTimers:
                NSLog(@"kCFRunLoopBeforeTimers");
                break;
            case kCFRunLoopBeforeSources:
                NSLog(@"kCFRunLoopBeforeSources");
                break;
            case kCFRunLoopBeforeWaiting:
                NSLog(@"kCFRunLoopBeforeWaiting");
                break;
            case kCFRunLoopAfterWaiting:
                NSLog(@"kCFRunLoopAfterWaiting");
                break;
            case kCFRunLoopExit:
                NSLog(@"kCFRunLoopExit");
                break;
            default:
                break;
        }
    }
    

    2.方式二(通过OC方式,也就是block方式)

      // 创建Observer
        CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(kCFAllocatorDefault, kCFRunLoopAllActivities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
            switch (activity) {
                case kCFRunLoopEntry: {
                    CFRunLoopMode mode = CFRunLoopCopyCurrentMode(CFRunLoopGetCurrent());
                    NSLog(@"kCFRunLoopEntry - %@", mode);
                    CFRelease(mode);
                    break;
                }
                    
                case kCFRunLoopExit: {
                    CFRunLoopMode mode = CFRunLoopCopyCurrentMode(CFRunLoopGetCurrent());
                    NSLog(@"kCFRunLoopExit - %@", mode);
                    CFRelease(mode);
                    break;
                }
                    
                default:
                    break;
            }
        });
        // 添加Observer到RunLoop中
        CFRunLoopAddObserver(CFRunLoopGetMain(), observer, kCFRunLoopCommonModes);
        // 释放
        CFRelease(observer);
    

    4.获取当前子线程中的runloop 整么做

    [NSRunLoop currentRunLoop];
    

    5.mainRunloop 和 CFRunloopGetMain() 有什么不一样

    mainRunloop 的实质也是 CFRunloopGetMain ,mainRunloop 是对 CFRunloopGetMain的封装

    相关文章

      网友评论

          本文标题:12.runloop问题

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