iOS开发——有关RunLoop

本文详细解析了RunLoop的概念、线程关系、对外接口、模式、内部逻辑和苹果如何利用RunLoop实现自动释放池、事件响应等功能。RunLoops是线程管理和事件处理的关键,与线程一一对应,通过CFRunLoopSourceRef和CFRunLoopTimerRef等接口处理事件。苹果在主线程RunLoop中注册Observer以处理AutoreleasePool、事件响应和定时器等任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

深入理解RunLoop

一篇很深入很深入的博文:深入理解RunLoop

苹果利用 RunLoop 实现自动释放池、延迟回调、触摸事件、屏幕刷新等功能的。

RunLoop 的概念

RunLoop 实际上就是一个对象,这个对象管理了其需要处理的事件和消息,并提供了一个入口函数来执行Event Loop 的逻辑(让线程能随时处理事件但并不退出,在没有处理消息时休眠以避免资源占用、在有消息到来时立刻被唤醒)

RunLoop 与线程的关系

CFRunLoop 是基于 pthread 来管理的
线程和 RunLoop 之间是一一对应的,线程刚创建时并没有 RunLoop,如果你不主动获取,那它一直都不会有。

RunLoop 对外的接口

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

  • CFRunLoopRef
  • CFRunLoopModeRef(没有暴露)
  • CFRunLoopSourceRef
  • CFRunLoopTimerRef
  • CFRunLoopObserverRef

RunLoop 的 Mode

你只能通过 mode name 来操作内部的 mode,当你传入一个新的 mode name 但 RunLoop 内部没有对应 mode 时,RunLoop会自动帮你创建对应的 CFRunLoopModeRef。对于一个 RunLoop 来说,其内部的 mode 只能增加不能删除。

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

RunLoop 的内部逻辑

这里写图片描述

CFRunLoopSourceRef 是事件产生的地方。Source有两个版本:Source0 和 Source1。

  • Source0 只包含了一个回调(函数指针),它并不能主动触发事件。使用时,你需要先调用 CFRunLoopSourceSignal(source),将这个 Source 标记为待处理,然后手动调用 CFRunLoopWakeUp(runloop) 来唤醒 RunLoop,让其处理这个事件。
  • Source1 包含了一个 mach_port 和一个回调(函数指针),被用于通过内核和其他线程相互发送消息。这种 Source 能主动唤醒 RunLoop 的线程。

实际上 RunLoop 就是这样一个函数,其内部是一个 do-while 循环

RunLoop 的底层实现

  • RunLoop 的核心是基于 mach port 的
  • RunLoop 的核心就是一个 mach_msg()

苹果用 RunLoop 实现的功能

  • AutoreleasePool
    App启动后,苹果在主线程 RunLoop 里注册了两个 Observer,一个监听回调释放池创建push,一个监听回调释放池释放pop
  • 事件响应
  • 手势识别
  • 界面更新
  • 定时器
  • PerformSelecter
  • 关于GCD:dispatch_async()
  • 网络请求

    AFNetwork: NSURLConnection传输网络时,内部使用RunLoop 来接收底层 socket 的事件,并通过之前添加的 Source0 通知到上层的 Delegate。

  • AsyncDisplayKit

ASDK 仿照 QuartzCore/UIKit 框架的模式,实现了一套类似的界面更新的机制:后台线程更改。即在主线程的 RunLoop 中添加一个 Observer,监听了 kCFRunLoopBeforeWaiting 和 kCFRunLoopExit 事件,在收到回调时,遍历所有之前放入队列的待处理的任务,然后一一执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值