12.runloop问题

问题

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问题)