前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS常用方法——RunLoop

iOS常用方法——RunLoop

作者头像
用户5521279
发布2020-02-14 14:21:45
7080
发布2020-02-14 14:21:45
举报
文章被收录于专栏:搜狗测试搜狗测试

前言

最近小编在阅读代码时发现开发同学在开发过程中使用到了一些runLoop,由于自身的好奇心作祟,于是就私下去了解了相关介绍,突然发现runLoop的作用远不止我最早之前理解的循环调用。接下来,小编就为大家简单介绍一下runLoop

RunLoop简介

RunLoop 实际上就是一种循环,在 “接收消息->等待->处理” 这样的循环中,去管理事件或者消息,例如触摸事件、UI刷新事件、定时器事件等。在消息来到时立刻被唤醒处理事件,在没有处理事件时休眠,避免资源占用。

iOS 系统中,提供了两个这样的对象:NSRunLoop 和 CFRunLoopRef。

CFRunLoopRef是在CoreFoundation 框架内的。

NSRunLoop是基于 CFRunLoopRef的封装,提供了面向对象的 API。

获得RunLoop对象方法

[NSRunLoop currentRunLoop]; // 获得当前线程的RunLoop对象
[NSRunLoop mainRunLoop]; // 获得主线程的RunLoop对象
CFRunLoopGetCurrent(); // 获得当前线程的RunLoop对象
CFRunLoopGetMain(); // 获得主线程的RunLoop对象

RunLoop与线程的关系

线程和 RunLoop 之间是一一对应的

CFRunLoop 是基于 pthread 来管理的。苹果不允许直接创建 RunLoop,它只提供了两个自动获取的函数:CFRunLoopGetMain() 和 CFRunLoopGetCurrent()。

RunLoop实现

在 CoreFoundation 里面关于 RunLoop 有5个类:

CFRunLoopRef CFRunLoopModeRef CFRunLoopSourceRef CFRunLoopTimerRef CFRunLoopObserverRef

其中 CFRunLoopModeRef 类并没有对外暴露,只是通过 CFRunLoopRef 的接口进行了封装。

一个 RunLoop 包含若干个 Mode,每个 Mode 又包含若干个Source/Timer/Observer。每次调用 RunLoop 的主函数时,只能指定其中一个 Mode,这个Mode被称作CurrentMode。如果需要切换 Mode,只能退出Loop,再重新指定一个 Mode 进入。这样做主要是为了分隔开不同组的 Source/Timer/Observer,让其互不影响。

每个Mode包含若干个Source、Timer、Observer,他们对应的类如下:

1. CFRunLoopSourceRef 是事件产生的地方

Source0 只包含了一个回调(函数指针),它并不能主动触发事件。

Source1 包含了一个 mach_port 和一个回调(函数指针),被用于通过内核和其他线程相互发送消息。

2. CFRunLoopTimerRef 是基于时间的触发器。

当其加入到 RunLoop 时,RunLoop会注册对应的时间点,当时间点到时,RunLoop会被唤醒以执行那个回调

3. CFRunLoopObserverRef 是观察者。

每个 Observer 都包含了一个回调(函数指针),当 RunLoop 的状态发生变化时,观察者就能通过回调接受到这个变化。

Source/Timer/Observer 被统称为 mode item,一个 item 可以被同时加入多个 mode。但一个 item 被重复加入同一个 mode 时是不会有效果的。如果一个 mode 中一个 item 都没有,则RunLoop 会直接退出,不进入循环。

RunLoop 这个对象,在 iOS 里由CFRunLoop 实现。简单来说,RunLoop 是用来监听输入源,进行调度处理的。这里的输入源可以是输入设备、网络、周期性或者延迟时间、异步回调。RunLoop 会接收两种类型的输入源:一种是来自另一个线程或者来自不同应用的异步消息;另一种是来自预订时间或者重复间隔的同步事件。

RunLoop使用场景

1.使用port或是自定义的input source来和其他线程进行通信 2.在线程(非主线程)中使用timer 3.使用 performSelector…系列(如performSelectorOnThread, …) 4.使用线程执行周期性工作

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-01-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 搜狗测试 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档