10.01-runloop

本文详细介绍了RunLoop的工作原理和应用,包括其基本作用、对象、线程关系、获取方式及核心类。RunLoop通过事件循环管理事件,节省CPU资源,维持程序运行。它与线程一一对应,每个线程有一个唯一的RunLoop对象。文中还提到了RunLoop的运行逻辑,如Source0、Source1、Timer和Observer,并展示了如何使用Observer监听RunLoop状态。在实际开发中,RunLoop可用于控制线程生命周期、解决NSTimer问题、监控应用卡顿和性能优化。此外,还讨论了如何配置定时器使其在滑动时不暂停工作。

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

实际上是一个对象,这个对象提供一个入口函数,执行这个入口函数后,程序会进入一个do…while循环,不断的处理事件,节省cpu资源,提高利用率.
通过内部维护的事件循环来对事件/消息进行管理的一个对象

  • 没有消息需要处理时,休眠以避免资源占用
  • 有消息需要处理时,立刻被唤醒

1. 基本作用

  1. 保持程序的持续运行
  2. 处理App中的各种事件(触摸事件,定时器事件,performSelect)
  3. 节省CPU资源,提高程序性能(该做事的时候做事,该休息的时候休息)

2. RunLoop对象

Foundation : NSRunLoop
Core Foundation : CFRunLoopRef

NSRunLoop 和 CFRunLoopRef都代表着RunLoop对象
NSRunLoop是基于CFRunLoopRef的一层OC包装


3. RunLoop与线程

  • 每条线程都有一个唯一的一个与之对应的RunLoop对象
  • RunLoop保存在一个全局的Dictionary里,线程为key, RunLoop为value
  • 线程刚刚创建的时候,并没有RunLoo对象,RunLoop会在第一次获取它的时候创建
  • RunLoop会在线程结束时销毁
  • 主线程的RunLoop已经自动获取(创建),子线程默认没有开启RunLoop

1. 获取runloop对象
//    Foundation
    [NSRunLoop currentRunLoop];//获取当前线程的runloop
    [NSRunLoop mainRunLoop];//获取主线程的runloop
    
//    Core Foundation
    CFRunLoopGetCurrent();//获取当前线程的runloop
    CFRunLoopGetMain();//获取主线程的runloop

2. RunLoop相关的类


  1. _pthread : 一个runloop对应一个_pthread线程.

  1. _modes : 一个runloop包含多个mode(默认模式,UI追踪模式,GSEventReceiveRunLoopMode)
  • 每个mode中又包含了若干个source/timer/observer
  • source/timer/observer 又叫做modeItem,不同mode下的modeitem互不影响

  1. _currentMode : 当前正在运行的模式,runloop只能运行在一种模式下. 如果要切换模式,退出当前正在运行的模式,然后重新定制的mode执行

在这里插入图片描述


  1. _commonModesItems : 加入NSRunLoopCommonModes模式下的对象会被放入这个集合中


  1. _commonModes : 里面包含了默认模式 和UI追踪模式
  • 如果mode中没有任何source0/source1/observer , runloop会立马退出

3. CFRunLoopObserverRef

  • 添加Observer监听RunLoop的所有状态

//    CFRunLoopObserverCreate(<#CFAllocatorRef allocator#>, <#CFOptionFlags activities#>, <#Boolean repeats#>, <#CFIndex order#>, <#CFRunLoopObserverCallBack callout#>, <#CFRunLoopObserverContext *context#>)
//CFRunLoopObserverContext 是一个结构体
    //创建observer
    CFRunLoopObserverRef observer = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopAllActivities, YES, 0, observerCallBack, NULL);
    //添加observer
    CFRunLoopAddObserver(CFRunLoopGetMain(), observer, kCFRunLoopDefaultMode);
    //通过create copy得到的, 最后都需要释放
    CFRelease(observer);

4. runloop的运行逻辑

  • source0
    触摸事件处理 , P而formSelector:onThread:
  • source1
    一般处理系统的事件
  • Timer
    NSTimer , performSelector:withObject:afterDelay:
  • Observers
    用于监听runloop的状态
    UI刷新(beforewaiting)
    autorelease pool (beforewaiting)


5.runloop在实际开发中的应用
  • 控制线程生命周期
  • 解决NSTimer在滑动时停止工作的问题
  • 监控应用卡顿
  • 性能优化

定时器

要想定时器在UI滑动的时候也不会停止工作

[[NSRunLoop currentRunLoop] addTimer:time forMode:NSRunLoopCommonModes];
    CFRunLoopAddTimer(<#CFRunLoopRef rl#>, <#CFRunLoopTimerRef timer#>, <#CFRunLoopMode mode#>)


把定时器加入了 _commonModeItems , (加入了默认模式,和UI追踪模式)

__CFRunLoopAddItemToCommonModes : 把timer添加到每一个mode中


runloop 流程


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值