Runloop底层原理分析
全栈老韩
全栈工程师,擅长iOS App开发、前端(vue、react、nuxt、小程序&Taro)开发、Flutter、React Native、后端(midwayjs、golang、express、koa)开发、docker容器、seo优化等。
Runloop
- Runloop一个运行循环,是一个对象.
- 包含一个do while循环
- 提供一个入口函数,程序可以进入一个do while循环
- 消息机制处理模式
C: 运行->计算->完成->退出
作用:
- 保持程序的持续进行
- 处理app中的各种事件(触摸、定时器、performSelecor)
- 节省cpu资源、提供程序的性能:该做事就做事,该休息就休息
处理
-
block应用:
__CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ -
调用timer用:
__CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ -
响应source0:
__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ -
响应source1:
__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ -
GCD主队列:
__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ -
observer源:
__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ -
线程和runloop通过key-value的形式一一对应.
-
子线程的runloop默认不开启
-
基于线程创建runloop
-
通过变量 -- 线程 -- runloop -- timer
-
timer依赖于runloop
NSThread *thread = [[NSThread alloc] initWithBlock:^{
NSLog(@"%@", [NSThread currentThread]);
[NSTimer scheduledTimerWithTimeInterval:1 repeats:YES block:^{
NSLog(@"子线程timer");
if (self.isStopping) {
[NSThread exit];
}
}];
[[NSRunloop currentRunLoop] run];
}];
thread.name = @"xxxxx";
[thread start];
- Timer为什么不准? \
- 在default和tracking mode切换.
- 一个runloop对应多个mode,一个mode对应于多个timer,source,observers.
- timer是如何加入runloop?
runLoopRun
runLoopDoBlocks
while循环执行item并执行timer等
timer加入的mode和我们现在runloop的mode相等
curr->_mode = KCFRunLoopCommonModes相等.
- timer一定要加入到相应的runloop的mode, timer加到items
- runloopRun -> doBlock -> while
- item->next
- doit
- block调用
-(void)cfTimerDemo {
CFRunLoopTimerContext context = {
0,
((__bridge void*)self),
NULL,
NULL,
NULL
};
CFRunLoopRef rlp = CFRunLoopGetCurrent();
/**
参数一:用于分配对象的内存
参数二:在什么时候触发(距离现在)
参数三:每个多少时间出发一次
参数四:未来参数
参数五:CFRunLoopObserver的优先级 当在RunLoop同一运行阶段中有多个CFRunLoopObserver 正常情况下使用0
参数六:回调,比如触发事件,我就会来到这里
参数七:上下文记录信息
*/
CFRunLoopTimerRef timerRef = CFRunLoopTimerCreate(kCFAllocatorDefault, 0, 1, 0, 0, lgRunLoopTimerCallBack, &context);
CFRunLoopAddTimer(rlp, timerRef, kCFRunLoopDefaultMode);
}
void lgRunLoopTimerCallBack(CFRunLoopTimerRef timer, void *info) {
NSLog(@"%@---%@", timer, info);
}
- observer
- 监听runloop的状态.
- 其demo和timer类似.
- source
-
source0,回调函数指针
-
一个signal 待处理
-
wake up唤醒runloop处理事件
-
作用:处理app内部事件
-
作用:app自己负责管理的事务, 触摸事件等 UIEvent、CFSocket
-
source1 mach_port & 回调函数指针
-
runloop和内核管理
-
port
-
线程之间通讯
-
实用技巧:
-
卡顿检测
-
FPS
发布于2024-01-29 15:18:53
浏览量64·
暂无评论,快来发表第一条评论吧