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

时间:2020-12-29 20:37:58

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] 即将进入睡眠