美文网首页iOS高级进阶
Runloop解析:成员信息

Runloop解析:成员信息

作者: 南城同學 | 来源:发表于2019-11-11 20:10 被阅读0次
    iOS中有2套API来访问和使用RunLoop
    • Foundation:NSRunLoop
    • CoreFoundation:CFRunLoopRef
    NSRunLoop和CFRunLoopRef都代表着RunLoop对象

    Runloop 相关的类
    • 主要的成员变量:
    struct __CFRunLoop {
        pthread_t _pthread;
        CFMutableSetRef _commonModes;
        CFMutableSetRef _commonModeItems;
        CFRunLoopModeRef _currentMode;
        CFMutableSetRef _modes;
        ......
    };
    
    struct __CFRunLoopMode {
    
        CFMutableSetRef _sources0;
        CFMutableSetRef _sources1;
        CFMutableArrayRef _observers;
        CFMutableArrayRef _timers;
    
        ......
    };
    
    
    1. CFRunLoopRef
    2. CFRunLoopModeRef:
    3. CFRunLoopSourceRef
    4. CFRunLoopTimerRef
    5. CFRunLoopObserverRef

    CFRunLoopModeRef

    1. CFRunLoopModeRef代表RunLoop的运行模式
    • 一个RunLoop包含若干个Mode(CFMutableSetRef _modes;),每个Mode又包含若干个Source0/Source1/Timer/Observer;
    • RunLoop启动时只能选择其中一个Mode,作为_currentMode;
    • 如果需要切换Mode,只能退出当前Loop,再重新选择一个Mode进入;
      1. 不同组的Source0/Source1/Timer/Observer能分隔开来,互不影响。
    • 如果Mode里没有任何Source0/Source1/Timer/Observer,RunLoop会立马退出。

    2. 常见的2种Mode
    • kCFRunLoopDefaultModeNSDefaultRunLoopMode):App的默认Mode,通常主线程是在这个Mode下运行

    • UITrackingRunLoopMode:界面跟踪 Mode,用于 ScrollView追踪触摸滑动,保证界面滑动时不受其他 Mode 影响。


    Runloop会选择一种模式来运行,那运行时究竟处理什么事呢 ?
    • 其实就是处理这四个事务:Source0/Source1/Timer/Observer
    1. Source0
    • 触摸事件处理
    • performSelector:onThread:
    2. Source1
    • 基于Port的线程间通信;
    • 系统事件捕捉:
      举例:runloop是如何来响应用户操作的 ?
      1. 用户点击屏幕时,source1捕捉系统事件;
      2. source1将事件包装成事件队列EventQueue
      3. 这个EventQueue又是在source0里处理的。
    3. Timer
    • NSTimer
    • performSelector:withObject:afterDelay:
    4. Observer
    • 用于监听RunLoop的状态;
    • UI刷新(BeforeWaiting);
      1. 举例:self.view.backgroundColor = [UIColor redColor];这句代码写完之后并不是立即生效,它是等 Observer监听到Runloop即将休眠了,进行UI刷新。
    • Autorelease pool(BeforeWaiting)。

    Observer 监听Runloop的各种状态

    
        // 创建Observer
        CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(kCFAllocatorDefault, kCFRunLoopAllActivities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
    
           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;
          }
        });
        // 添加Observer到RunLoop中
        CFRunLoopAddObserver(CFRunLoopGetMain(), observer, kCFRunLoopCommonModes);
        // 释放
        CFRelease(observer);
    

    相关文章

      网友评论

        本文标题:Runloop解析:成员信息

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