美文网首页
RunLoop -- CFRunLoopObserverRef

RunLoop -- CFRunLoopObserverRef

作者: 踩坑小分队 | 来源:发表于2020-04-11 21:22 被阅读0次

    有的时候我们也会自己创建一些Observer去监听RunLoop的状态
    RunLoop的状态

    typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
        kCFRunLoopEntry = (1UL << 0),           //  即将进入Loop
        kCFRunLoopBeforeTimers = (1UL << 1),    // 即将处理Timer
        kCFRunLoopBeforeSources = (1UL << 2),   // 即将处理Sources
        kCFRunLoopBeforeWaiting = (1UL << 5),   // 即将进入休眠
        kCFRunLoopAfterWaiting = (1UL << 6),    // 即将休眠结束
        kCFRunLoopExit = (1UL << 7),            // 退出Loop
        kCFRunLoopAllActivities = 0x0FFFFFFFU   // 上面所有的状态
    };
    

    接下来,监听一下RunLoop的状态
    方法一

    // CFRunLoopObserverCallBack 按照这个方法的格式进行创建
    void myCFRunLoopObserverCallBack(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) {
        switch (activity) {
            case kCFRunLoopEntry:
                NSLog(@"即将进入Loop");
                break;
            case kCFRunLoopBeforeTimers:
                NSLog(@"即将进入Timers");
            break;
            case kCFRunLoopBeforeSources:
                NSLog(@"即将进入Source");
            break;
            case kCFRunLoopBeforeWaiting:
                NSLog(@"即将进入休眠");
            break;
            case kCFRunLoopAfterWaiting:
                NSLog(@"即将结束休眠");
            break;
            case kCFRunLoopExit:
                NSLog(@"即将退出Loop");
            break;
            default:
                break;
        }
    }
    
    /// RunLoop创建RunLoopObserver
        /// @param CFAllocatorRef allocator 指定分配器创建对象,一般写NULL或者kCFAllocatorDefault
        /// @param CFOptionFlags activities 想要监听什么状态,这里监听所有的状态
        /// @param Boolean repeats 是否重复监听
        /// @param CFIndex order 不需要考虑顺序,写0
        /// @param CFRunLoopObserverCallBack callout 按照格式定义一个回调函数
        /// @param CFRunLoopObserverContext *context 传递给监听函数的参数,可以传NULL
        CFRunLoopObserverRef observer = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopAllActivities, YES, 0, myCFRunLoopObserverCallBack, NULL);
        
        
        /// RunLoop添加Observer
        /// @param CFRunLoopRef rl 相关监听的RunLoop,这里监听主线程的RunLoop
        /// @param CFRunLoopObserverRef observer 创建的CFRunLoopObserver
        /// @param CFRunLoopMode RunLoop的模式<kCFRunLoopCommonModes包含两种模式>
        
        CFRunLoopAddObserver(CFRunLoopGetMain(), observer, kCFRunLoopCommonModes);
        
        // C语言创建的对象,最后需要释放
        CFRelease(observer);
    

    CFRunLoopMode

    /**
    1. kCFRunLoopDefaultMode:App的默认Mode,通常主线程是在这个Mode下运行
    2. UITrackingRunLoopMode:界面跟踪 Mode,用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他 Mode 影响
    3. UIInitializationRunLoopMode: 在刚启动 App 时第进入的第一个 Mode,启动完成后就不再使用
    4. GSEventReceiveRunLoopMode: 接受系统事件的内部 Mode,通常用不到
    5. kCFRunLoopCommonModes: 这是一个占位用的Mode,作为标记kCFRunLoopDefaultMode和UITrackingRunLoopMode用,并不是一种真正的Mode
    */

    方法二

    /// RunLoop创建RunLoopObserver
        /// @param CFAllocatorRef allocator 指定分配器创建对象,一般写NULL或者kCFAllocatorDefault
        /// @param CFOptionFlags activities 想要监听什么状态,这里监听所有的状态
        /// @param Boolean repeats 是否重复监听
        /// @param CFIndex order 不需要考虑顺序,写0
        /// @param 回调方法
        CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(kCFAllocatorDefault, kCFRunLoopAllActivities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
            switch (activity) {
                   case kCFRunLoopEntry:
                       NSLog(@"即将进入Loop");
                       break;
                   case kCFRunLoopBeforeTimers:
                       NSLog(@"即将进入Timers");
                   break;
                   case kCFRunLoopBeforeSources:
                       NSLog(@"即将进入Source");
                   break;
                   case kCFRunLoopBeforeWaiting:
                       NSLog(@"即将进入休眠");
                   break;
                   case kCFRunLoopAfterWaiting:
                       NSLog(@"即将结束休眠");
                   break;
                   case kCFRunLoopExit:
                       NSLog(@"即将退出Loop");
                   break;
                   default:
                       break;
               }
        });
        
        /// RunLoop添加Observer
        /// @param CFRunLoopRef rl 相关监听的RunLoop,这里监听主线程的RunLoop
        /// @param CFRunLoopObserverRef observer 创建的CFRunLoopObserver
        /// @param CFRunLoopMode RunLoop的模式<kCFRunLoopCommonModes包含两种模式>
        
        CFRunLoopAddObserver(CFRunLoopGetMain(), observer, kCFRunLoopCommonModes);
        CFRelease(observer);
    

    和上面的方法一,大同小异,只不过是回调方法换成了block
    测试一下

    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        NSLog(@"点击了屏幕 -- ");
    }
    
    即将结束休眠
    即将进入Timers
    即将进入Source
    点击了屏幕 -- 
    

    可以看到相关的监听
    测试下Mode的切换

    // CFRunLoopObserverCallBack 按照这个方法的格式进行创建
    void myCFRunLoopObserverCallBack(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) {
        CFRunLoopMode mode;
        switch (activity) {
            case kCFRunLoopEntry:
                
                mode = CFRunLoopCopyCurrentMode(CFRunLoopGetMain());
                NSLog(@"即将进入Loop  %@",mode);
                CFRelease(mode);
                break;
    //        case kCFRunLoopBeforeTimers:
    //            NSLog(@"即将进入Timers");
    //        break;
    //        case kCFRunLoopBeforeSources:
    //            NSLog(@"即将进入Source");
    //        break;
    //        case kCFRunLoopBeforeWaiting:
    //            NSLog(@"即将进入休眠");
    //        break;
    //        case kCFRunLoopAfterWaiting:
    //            NSLog(@"即将结束休眠");
    //        break;
            case kCFRunLoopExit:
                mode = CFRunLoopCopyCurrentMode(CFRunLoopGetMain());
                NSLog(@"即将退出Loop  %@",mode);
                CFRelease(mode);
            break;
            default:
                break;
        }
    }
    

    给当前界面添加一个ScrollView,滚动下查看相关的监听,在滑动开始和滑动结束,会发现相关Mode的切换情况

    即将退出Loop  kCFRunLoopDefaultMode
    即将进入Loop  UITrackingRunLoopMode
    即将退出Loop  UITrackingRunLoopMode
    即将进入Loop  kCFRunLoopDefaultMode
    

    相关文章

      网友评论

          本文标题:RunLoop -- CFRunLoopObserverRef

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