欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS学习笔记-138.RunLoop06——Runloop相关类4_ CFRunloopSourceRef和CFRunLoopObserverRef

程序员文章站 2022-05-16 10:05:13
runloop06——runloop相关类4_ cfrunloopsourceref和cfrunloopobserverref 一、cfrunloopsourceref 1....

runloop06——runloop相关类4_ cfrunloopsourceref和cfrunloopobserverref

一、cfrunloopsourceref

1.是事件源也就是输入源,有两种分类模式;

一种是按照苹果官方文档进行划分的

另一种是基于函数的调用栈来进行划分的(source0和source1)。

2.具体的分类情况

(1)以前的分法

port-based sources

custom input sources

cocoa perform selector sources

(2)现在的分法

source0:非基于port的(用户主动出发的)

source1:基于port的(系统内部的消息事件)

3.可以通过打断点的方式查看一个方法的函数调用栈


二、cfrunloopobserverref

cfrunloopobserverref是观察者,能够监听runloop的状态改变

2.1 如何监听

//创建一个runloop监听者
cfrunloopobserverref observer = cfrunloopobservercreatewithhandler(cfallocatorgetdefault(),kcfrunloopallactivities, yes, 0, ^(cfrunloopobserverref observer, cfrunloopactivity activity) {

    nslog(@"监听runloop状态改变---%zd",activity);
});

//为runloop添加一个监听者
cfrunloopaddobserver(cfrunloopgetcurrent(), observer, kcfrunloopdefaultmode);

cfrelease(observer);

2.2 代码示例

//
//  viewcontroller.m
//  03_uiview93_ cfrunloopobserverref和cfrunloopsourceref
//
//  created by 杞文明 on 17/9/11.
//  copyright ? 2017年 杞文明. all rights reserved.
//

#import "viewcontroller.h"

@interface viewcontroller ()
@end

@implementation viewcontroller

-(void)viewdidload{
    [self observercreate];
}

- (ibaction)btnclick:(id)sender {
    nslog(@"----%s",__func__);
}

-(void)observercreate{
    //1.创建监听者
    /*
      第一个参数:怎么分配存储空间
      第二个参数:要监听的状态 。kcfrunloopallactivities 所有的状态
      第三个参数:是否持续监听
      第四个参数:优先级 总是传0
      第五个参数:当状态改变时候的回调
      */
    cfrunloopobserverref observer = cfrunloopobservercreatewithhandler(cfallocatorgetdefault(), kcfrunloopallactivities, yes, 0, ^(cfrunloopobserverref observer, cfrunloopactivity activity) {
        switch (activity) {
            case kcfrunloopentry:
                nslog(@"即将进入runloop");
                break;
            case kcfrunloopbeforetimers:
                nslog(@"即将处理timer事件");
                break;
            case kcfrunloopbeforesources:
                nslog(@"即将处理source事件");
                break;
            case kcfrunloopbeforewaiting:
                nslog(@"即将进入睡眠");
                break;
            case kcfrunloopafterwaiting:
                nslog(@"被唤醒");
                break;
            case kcfrunloopexit:
                nslog(@"runloop退出");
                break;

            default:
                break;
        }
    });

    //2.添加监听者
    /*
       第一个参数:要监听哪个runloop
       第二个参数:观察者
       第三个参数:运行模式
       */
    cfrunloopaddobserver(cfrunloopgetcurrent(), observer, kcfrunloopdefaultmode);
}

@end

2.3 cfrunloopactivity

typedef cf_options(cfoptionflags, cfrunloopactivity) {
    kcfrunloopentry = (1ul << 0),           即将进入runloop
    kcfrunloopbeforetimers = (1ul << 1),    即将处理timer事件
    kcfrunloopbeforesources = (1ul << 2),   即将处理source事件
    kcfrunloopbeforewaiting = (1ul << 5),   即将进入睡眠
    kcfrunloopafterwaiting = (1ul << 6),    被唤醒
    kcfrunloopexit = (1ul << 7),            runloop退出
    kcfrunloopallactivities = 0x0fffffffu
};

2.4 图示

iOS学习笔记-138.RunLoop06——Runloop相关类4_ CFRunloopSourceRef和CFRunLoopObserverRef

2.5 运行结果

[74454:384907] 被唤醒
[74454:384907] 即将处理timer事件
[74454:384907] 即将处理source事件
[74454:384907] 即将处理timer事件
[74454:384907] 即将处理source事件
[74454:384907] 即将处理timer事件
[74454:384907] 即将处理source事件
[74454:384907] 即将处理timer事件
[74454:384907] 即将处理source事件
[74454:384907] 即将进入睡眠
[74454:384907] 被唤醒
[74454:384907] 即将处理timer事件
[74454:384907] 即将处理source事件
[74454:384907] 即将处理timer事件
[74454:384907] 即将处理source事件
[74454:384907] -----[viewcontroller btnclick:]
[74454:384907] 即将处理timer事件
[74454:384907] 即将处理source事件
[74454:384907] 即将进入睡眠