以上是完整的 CFRunLoop 和 CFRunLoopMode 的结构体源码(太长了我的妈,用不着看完),下面我精简一下,把重要的留下,看如下代码(可以仔细看一下,加深印象):


上面是精简出来比较关键的 RunLoop 和 RunLoopMode 的结构体,从上面源码可以看出:

一个 RunLoop 对象有一个用来被唤醒的端口 _wakeUpPort,一个当前运行的 mode 叫 _currentMode,以及若干个 _modes_commonModes_commonModeItems(commonModes这2个东西后面详细讲)。runLoop 有很多 mode,即 _modes,但是只有一个 _currentMode,RunLoop 一次只能运行在一个 mode 下,如果需要切换 Mode,只能退出 Loop,不可能在多个 Mode 下同时运行(这是iOS运行流畅的原因之一)。

从 runLoopMode 的组成可以看出来:mode管理了所有的事件(Source/Timer/Observer 被称为 Mode Item),而 RunLoop 管理着若干个 mode。

这两个结构体中,已经涉及到了我们的所有五个类了,关于他们的关系我后面会详细说,这里简单的看看,对他们有个印象,混个脸熟,先来看 CFRunLoopSourceRef

CFRunLoopSourceRef

在我 RunLoopMode 数据结构代码中可以看到这两个东西 CFMutableSetRef _source0 和 CFMutableSetRef _source1,首先这两个东西是 Set(集合),集合中存放的是一堆数据结构(这里就可以对应上面蓝色底那张图来看,这是那种图图里面的Source集合的部分),那这个 source 到底是个什么东西呢,在 RunLoopMode 结构体的注释中我也写了,他们其实也是一个数据结构 CFRunLoopSourceRef。那 CFRunLoopSourceRef 结构又是怎样的呢,我们再来看下面它的结构代码:


上面代码贴出来了三个数据结构,其他多余的别看,光看我注释的部分就行,其中第一个数据结构 __CFRunLoopSource 包含一个 _context 成员,他的类型是 CFRunLoopSourceContext 或者是 CFRunLoopSourceContext1,也就是后面两个数据结构。

大家可以从我重点看我注释的行 CFRunLoopSourceContext(其实就是source0的数据结构)和 CFRunLoopSourceContext1(source1) 的区别就在于 CFRunLoopSourceContext1(source1) 多了一个 mach_port_t 接收消息的端口。mach_port_t 这又是个什么玩意儿,这里暂时不用管,可以简单的啰嗦两句,mach是iOS系统内核的心脏,他管理着处理器的资源,关于它的一些结构和原理,我以后会写一篇文章来描述它的结构和工作原理,现在我还是把话收回来说主题,不走远了。

这里简单总结一下:

  • CFRunLoopSourceRef 是事件产生的地方;
  • 这个 CFRunLoopSourceRef 有两个版本就是 source0 和 source1;
  • source0只包含一个回调(函数指针),不能主动出发事件,需要 CFRunLoopSourceSignal(source) 将 Source 标记为待处理,CFRunLoopWakeUp(runloop) 唤醒 RunLoop,让其处理事件
  • source1包含 mach_port 和一个回调(函数指针),用于通过内核和其它线程相互发送消息,能主动唤醒 RunLoop。

http://www.cnblogs.com/CrazyD0u/p/6481092.html

      • 我们在这里绑定了两个参数一个是signal触发的函数,一个是函数的参数,至于其他参数的用途,可以看看苹果官方文档的说明:
    • version
    • Version number of the structure. Must be 0.
    • info
    • An arbitrary pointer to program-defined data, which can be associated with the CFRunLoopSource at creation time. This pointer is passed to all the callbacks defined in the context.
    • retain
    • A retain callback for your program-defined info pointer. Can be NULL.
    • release
    • A release callback for your program-defined info pointer. Can be NULL.
    • copyDescription
    • A copy description callback for your program-defined info pointer. Can be NULL.
    • equal
    • An equality test callback for your program-defined info pointer. Can be NULL.
    • hash
    • A hash calculation callback for your program-defined info pointer. Can be NULL.
    • schedule
    • A scheduling callback for the run loop source. This callback is called when the source is added to a run loop mode. Can be NULL.
    • cancel
    • A cancel callback for the run loop source. This callback is called when the source is removed from a run loop mode. Can be NULL.
    • perform
    • A perform callback for the run loop source. This callback is called when the source has fired.

runloop的source的更多相关文章

  1. iOS开发RunLoop学习:三:Runloop相关类(source和Observer)

    一:RunLoop相关类: 其中:source0指的是非基于端口por,说白了也就是处理触摸事件,selector事件,source1指的是基于端口的port:是处理系统的一些事件 注意:创建一个Ru ...

  2. iOS多线程-RunLoop简介

    什么是RunLoop? 从字面上来看是运行循环的意思. 内部就是一个do{}while循环,在这个循环里内部不断的处理各种任务(比如:source/timer/Observer) RunLoop的存在 ...

  3. 深入理解RunLoop

    网上看的一篇文章,写的真好,我得多看几次好好理解理解 膜拜大神,转载至此便于学习查看. 此处标明原文链接:http://blog.ibireme.com/2015/05/18/runloop/    ...

  4. 浅谈Runloop

    RunLoop 是 iOS 和 OS X 开发中非常基础的一个概念,这篇文章将从 CFRunLoop 的源码入手,介绍 RunLoop 的概念以及底层实现原理.之后会介绍一下在 iOS 中,苹果是如何 ...

  5. Runloop 深入理解(转)

    RunLoop 是 iOS 和 OSX 开发中非常基础的一个概念,这篇文章将从 CFRunLoop 的源码入手,介绍 RunLoop 的概念以及底层实现原理.之后会介绍一下在 iOS 中,苹果是如何利 ...

  6. RunLoop的深入了解

    RunLoop 是 iOS 和 OS X 开发中非常基础的一个概念,这篇文章将从 CFRunLoop 的源码入手,介绍 RunLoop 的概念以及底层实现原理.之后会介绍一下在 iOS 中,苹果是如何 ...

  7. iOS 深入理解RunLoop

    RunLoop 是 iOS 和 OSX 开发中非常基础的一个概念,这篇文章将从 CFRunLoop 的源码入手,介绍 RunLoop 的概念以及底层实现原理.之后会介绍一下在 iOS 中,苹果是如何利 ...

  8. runloop之于thread

    做一个技术方向久了,难免会沉溺其中,对当初开始接触这个方向的许多根本上的疑问渐渐都不了了之,意识上认为然,而不知其所以然. 最近重新梳理iOS的runloop,说说自己的理解,希望能说清楚. 先抛出一 ...

  9. 【转】深入理解RunLoop

    RunLoop 是 iOS 和 OS X 开发中非常基础的一个概念,这篇文章将从 CFRunLoop 的源码入手,介绍 RunLoop 的概念以及底层实现原理.之后会介绍一下在 iOS 中,苹果是如何 ...

随机推荐

  1. UWP 利用DataGrid控件创建表格

    通过 Nuget 搜索 Microsoft.Toolkit.Uwp.UI.Controls.DataGrid 安装库,在XAML文件中添加引用库 xmlns:controls="using: ...

  2. MongoDB 学习笔记(七):主从复制与副本集

    一.主从复制 1.主从复制是一个简单的数据库同步备份的集群技术,如下图:要明确的知道主服务器与从服务器,且从服务器要明确的知道主服务器的存在. 2.在MongoDB中在启动数据库服务时,可以用mast ...

  3. NOIP 膜你题 DAY2

    NOIp膜你题   Day2 duliu 出题人:ZAY     题解 这就是一道组合数问题鸭!!!  可是泥为什么没有推出式子!! 首先我们知道的是 m 盆花都要摆上,然后他们的顺序不定(主人公忘记 ...

  4. BZOJ 1602: [Usaco2008 Oct]牧场行走 倍增裸题

    Description N头牛(2<=n<=1000)别人被标记为1到n,在同样被标记1到n的n块土地上吃草,第i头牛在第i块牧场吃草. 这n块土地被n-1条边连接. 奶牛可以在边上行走, ...

  5. Vue学习之路第十八篇:私有过滤器的使用

    1.上篇已经介绍了全局过滤器的使用,“全局”顾名思义就是一次定义处处使用,可以被一个页面里不同的Vue对象所使用,如下代码所示: <body> <div id="app1& ...

  6. MySQL数据库中字段类型为tinyint,读取出来为true/false的问题

    由于MySQL中没有boolean类型,所以会用到tinyint类型来表示. 数据库一个表中有一个tinyint类型的字段,值为0或者1,如果取出来的话,0会变成false,1会变成true.

  7. Windows常用软件

    目录 Uninstall Tool FACapture Unlocker Uninstall Tool Uninstall Tool 这是一款可以彻底删除应用的软件,能连通注册表内容一起删除. FAC ...

  8. HDU 4358

    看了题解那个弱化版后,马上就去做了HDU 3333这道题,发现有可用的地方.于是往这方面想,主要是处理如何确定一个数出现K次的问题.想到了从左往右把每个数出现的次数记下来,但感觉不是这样,呃,再看别人 ...

  9. Redis源代码分析(二十二)--- networking网络协议传输

    上次我仅仅分析了Redis网络部分的代码一部分,今天我把networking的代码实现部分也学习了一遍,netWorking的代码很多其它偏重的是Clientclient的操作.里面addReply( ...

  10. Google C++ style guide——格式

    1.行长度 每一行代码字符数不超过80. 例外: 1)假设一行凝视包括了超过80字符的命令或URL,出于复制粘贴的方便能够超过80字符: 2)包括长路径的能够超出80列,尽量避免: 3)头文件保护能够 ...