RunLoop学习总结

2020-04-10  本文已影响0人  大写的空气

通过以下文章学习记录

关于Runloop的原理探究及基本使用

深入理解RunLoop

RunLoop完全指南

RunLoop: 消息循环、运行循环、跑圈

RunLoop内部实际是一个do-while循环

RunLoop在第一次获取时创建,线程结束时销毁;子线程不手动获取RunLoop,它一直不会存在

一个RunLoop可以有多个mode, 每个mode包含若干个mode item: source(set对象)、timer(array对象)、observer(array对象)

由于每个mode都是一个mutableset对象,因此item被重复加入同一个mode不会有效果;当mode中不存在item时,RunLoop退出,换句话说,mode中不存在item时,调用 runloop run方法也不会执行

+ source0: 使用时先调用CFRunLoopSourceSignal(source),标志位待处理,后手动调用CFRunLoopWakeUp(runloop)来唤醒RunLoop, 让处理这个事件

-performSelector:onThread:withObject:waitUntilDone: inModes:创建的是source0任务。

+ source1: 基于port,能主动唤醒runloop

> source1和timer都属于端口事件源,所有的timer都共用一个端口(timer port)

+ timer: CFRunLoopTimerRef, 在预设的时间点唤醒runloop执行回调,不是实时的

+ observer: CFRunLoopObserverRef观察者,监听runloop状态, 不属于runloop事件源

### 休眠与唤醒

依靠系统内核来完成,核心组件Darwin中的Mach。Mach的对象只能通过消息传递的方式实现对象间通信,消息在两个端口(port)间传递。

通过mach_msg()函数接收、发送消息,会触发内核状态切换,当在用户态调用时会触发陷阱机制,切换到内核态完成实际工作。RunLoop休眠时(mach_msg_trap状态)

#### timer正确执行方式

// 参数1:间隔时间 参数2:对象 参数3:方法 参数4:自定义 参数5:是否重复执行NSTimer*timer=[NSTimer timerWithTimeInterval:1target:selfselector:@selector(task)userInfo:nil repeats:YES];//把定时源加入到当前线程下的消息循环中[[NSRunLoop currentRunLoop]addTimer:timer forMode:NSRunLoopCommonModes];

线程中启动runloop,如果想runloop考研终止,使用下面方法

''' 

BOOL shouldKeepRunning=YES;//全局变量

NSRunLoop*theRL=[NSRunLoop currentRunLoop];

while(shouldKeepRunning&&[theRL runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);

''' 

如果没有输入源,runloop马上就退出,解决此问题可以使用

''' 

//加个端口的源

[[NSRunLoop currentRunLoop]addPort:[NSPort port]forMode:NSDefaultRunLoopMode];

while(YES&&[[NSRunLoop currentRunLoop]runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);

''' 

>  用户触发事件, IOKit.framework 生成一个 IOHIDEvent 事件并由 SpringBoard 接收,SpringBoard会利用mach port,产生source1,来唤醒目标APP的com.apple.uikit.eventfetch-thread的RunLoop。Eventfetch thread会将main runloop 中__handleEventQueue所对应的source0设置为signalled == Yes状态,同时唤醒main RunLoop。mainRunLoop则调用__handleEventQueue进行事件队列处理。

### RunLoop应用

+ 事件响应

+ 手势识别

+ 界面刷新

+ NSTimer

+ PerformSelector:afterDealy/PerformSelectorOnThread(mainThread):

+ dispatch to main queue

+ 线程保活

上一篇 下一篇

猜你喜欢

热点阅读