RunLoop理解(一)

58 篇文章 2 订阅
35 篇文章 0 订阅

一、Event Loop & Cocoa RunLoop

宏观上:Event Loop

1.RunLoop是一个用于循环监听和处理事件或者消息的模型,接收请求,然后派发给相关的处理模块。

2.Cocoa RunLoop属于EventLoop模型在Mac平台的具体实现

微观上: Cocoa RunLoop

1.Cocoa RunLoop本质上就是一个对象,提供一个入口函数启动事件循环,在满足特点条件后才会退出。

2.Cocoa RunLoop与普通while/for循环不同的是它能监听处理事件和消息,能智能休眠和被唤醒,这些功能的实现依赖于Mac Port。

二、 Cocoa RunLoop的内部结构

在这里插入图片描述

RunLoop架构划分为四个部分:

1.事件源

2.运行模式

3.循环机制

4.执行反馈

1. 事件源

Cocoa RunLoop接受的事件源分为两种类型:Input Sources 和 Timer Sources

1.1. Input Sources

Input Sources通过异步派发的方式将事件转送到目标线程,事件类别分为两大块:

Port-Based Sources :

基于Mach端口的事件源,Cocoa和Core Foundation这两个框架已经提供了内部支持,只需要调用端口相关的对象或者函数就能提供端口进行通信。比如:将NSPort对象部署到RunLoop中,实现两个线程的循环通信。

Custom Input Sources:

用户自定义的输入源:使用Core Foundation框架中CFRunLoopSourceRef对象的相关函数实现。

Cocoa Perform Selector Sources:Cocoa框架内部实现的自定义输入源,可以跨线程调用,实现线程间通信,有点类似于Port-Based事件源,不同的是这种事件源只在RunLoop上部署一次,执行结束后便会自动移除。如果目标线程中没有启动RunLoop也就意味着无法部署着泪事件源,因此不会得到预期的结果。

使用Cocoa自定义事件源的函数接口,如下:

   //部署在主线程
   //参数列表:Selector:事件源处理函数,Selector参数,是否阻塞当前线程,指定RunLoop模式
   performSelectorOnMainThread:withObject:waitUntilDone:
   performSelectorOnMainThread:withObject:waitUntilDone:modes:
   
   //部署在指定线程
   //参数列表:Selector:事件源处理函数,指定线程,Selector参数,是否阻塞当前线程,指定RunLoop模式
   permSelector:onThread:withObject:waitUntilDone:
   performSelector:onThread:withObject:waitUntilDone:modes:
   
   //部署在当前线程
   //参数列表:Selector:事件源处理函数,Selector参数,延时执行时间,指定RunLoop模式
   performSelector:withObject:afterDelay:
   performSelector:withObject:afterDelay:inModes:
    
   //撤销某个对象通过函数performSelector:withObject:afterDelay:部署在当前线程的全部或者指定事件源
   cancelPreviousPerformRequestsWithTarget:
   cancelPreviousPerformRequestsWithTarget:selector:object:

综上,Input Sources包括基于Mach端口的事件源和自定义的事件源,二者的唯一区别在于被触发的方式:前者是有内核自动触发,后者则需要在其他线程中手动触发。

1.2. Timer Sources

不同于Input Source的异步派发,Timer Source是通过派发的方式,在预设时间到达时将事件转送到目标线程。这种事件源可用于线程的自我提醒功能,实现周期性的任务。

​ 如果RunLoop当前运行模式没有添加Time Source,则在Run Loop中部署的定时器不会被执行。

​ 设定的间隔时间于真实的触发时间之间没有必然联系,定时器会根据设定的间隔时间周期性的派发消息到RunLoop,但是真实的触发时间由RunLoop决定,假设RunLoop当前正在处理奇异果长时间的任务,则触发时间会被延迟,如果在最终触发之前Timer已经派发了N个消息,RunLoop也只会当做一次派发对待,触发一次对应的处理函数。

2. 运行模式

运行模式类似于一个过滤器,用于屏蔽那些不关心的事件源,让RunLoop专注于监听和处理指定的事件源和RunLoop Observer。

CDRunLoopMode和CFRunLoop的数据结构大致如下:

    struct __CFRunLoop {
        CFMutableSetRef _commonModes;     // Set
        CFMutableSetRef _commonModeItems; // Set<Source/Observer/Timer>
        CFRunLoopModeRef _currentMode;    // Current Runloop Mode
        CFMutableSetRef _modes;           // Set
        ...
    };
    
    struct __CFRunLoopMode {
        CFStringRef _name;            // Mode Name, 例如 @"kCFRunLoopDefaultMode"
        CFMutableSetRef _sources0;    // Set
        CFMutableSetRef _sources1;    // Set
        CFMutableArrayRef _observers; // Array
        CFMutableArrayRef _timers;    // Array
        ...
    };

结合以上源吗:总结如下:

每种模式通过name属性作为标识。

一种运行模式(Run Loop Mode)就是一个集合,包含需要监听的事件源Input Sources和Timer Sources以及需要触发的RunLoop observers。

RunLoop简介:

运行循环,在程序运行过程中循环做一些事情(如接收消息、处理消息、休眠等待等);

RunLoop是通过内部维护的事件循环来对事件/消息进行管理的一个对象;

RunLoop不是一个简单的do…while循环,它涉及到用户态和内核之间的切换。

事件循环:

事件循环就是对事件/消息进行管理,事件循环可以达到:

没有消息需要处理时,休眠线程以避免资源占用。从用户态切换到内核态,等待消息;

有消息需要处理时,立刻唤醒线程,回到用户态处理消息;

通过调用mach_msg()函数类转移当前线程的控制权给内核态/用户态。

RunLoop的应用范畴

定时器(Timer)、Performselector

GCD:dispatch_async(dispatch_get_main_queue(),^{});

事件响应、手势识别、界面刷新

网络请求

AuterreleasePool

RunLoop 对象

ios中有2套API来访问和使用RunLoop:

​ 1、Foundation:NSRunLoop(是CFRunLoopRef 的封装,提供了面向对象的API)

​ 2.Core Foundation;CFRunLoopRef

NSRunLoop 和 CFRunLoopRef

NSRunLoop和CFRunLoopRef都代表着RunLoop对象

NSRunLoop不开源,而CFRunLoopRef是开源的:Core Foundation 源码

  • 获取RunLoop对象的方式:
    // Foundation
    [NSRunLoop mainRunLoop];     // 获取主线程的 RunLoop 对象
    [NSRunLoop currentRunLoop];  // 获取当前线程的 RunLoop 对象
    // Core Foundation
    CFRunLoopGetMain();     // 获取主线程的 RunLoop 对象
    CFRunLoopGetCurrent();  // 获取当前线程的 RunLoop 对象

RunLoop在实际开发中的应用

1.使用端口或自定义输入源与其他线程进行通信

2.在子线程上使用定时器

3.解决NSTimer在滑动时停止工作的问题

4.控制线程的生命周期,实现一个常驻线程

5.在Cocoa应用程序中使用任何performSelector…方法

监控应用卡顿

性能优化

相关链接

苹果官方文档 RunLoop

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值