RunLoop总结

什么是RunLoop

Runloop视频
这个视频讲得很好,看完收获很大,对RunLoop有概念了,并且了解了一些应用。尤其是前面那个子线程timer的例子,一步一步递进,容易理解,建议多看几遍。
从这个例子开始了解,创建计时器:
主线程添加计时器

RunLoop总结_第1张图片
主线程添加计时器

上面的scheduledTimerWithTimeInterval是对下面的封装。是添加到NSRunLoop的默认模式,还是要用下面的方式创建加timer。

子线程添加计时器

  • 一条线程的生命只能由它的任务保住,让线程有执行不完的任务,线程就不会释放了。
  • 一条线程上面的RunLoop默认是不循环的,要手动run起来。[[NSRunLoop currentRunLoop] run]死循环,和while(true)一样,但是更多内容。
  • 执行currentRunLoop() 第一次获取RunLoop的时候才创建,属于懒加载。
  • 暴力退出线程 [NSThread exit];


    RunLoop总结_第2张图片

    RunLoop总结_第3张图片

CFRunLoopRun的伪代码 Runloop培训视频有讲解
两小时二十五分钟开始听比较好。

__CFRunLoopRun {
    do {
        __CFRunLoopDoBlocks 处理 block
        __CFRunLoopDoSources0 处理 source0
        if (判断是否有其他消息需要处理,如果有) {
            goto: handler_msg(处理消息模块)
        }
        __CFRunLoopServiceMachPort(wait) 准备休眠 阻塞 // 如果有消息来了,需要处理就醒了
       handle_msg: (处理消息模块:timer, gcd, __CFRunLoopDoSource1)

    } while(1)
}

从字面上看

  • 运行循环
  • 跑圈

基本作用

  • 保持程序的持续运行(比如主运行循环)
  • 处理APP中的各种事件(比如触摸事件、定时器事件、Selector事件)
  • 节省CPU资源,提高程序性能:该做事时做事,该休息时休息

存在价值

RunLoop总结_第4张图片
没有RunLoop

RunLoop总结_第5张图片
有RunLoop

RunLoop总结_第6张图片
主运行循环

RunLoop 对象

  • iOS中有两套API来访问和使用RunLoop
    1. Foundation(NSRunLoop)
    2. Core Foundation(CFRunLoopRef)
  • NSRunLoop 和 CFRunLoopRef 都代表着 RunLoop 对象
  • NSRunLoop 是基于 CFRunLoopRef 的一层OC包装,所以要了解 RunLoop 内部结构,多研究 CFRunLoopRef 层面的 API(CoreFoundation层面)

RunLoop 与多线程

  • 每条线程都有唯一的一个与之对应的 RunLoop 对象
  • 主线程的RunLoop 已经自动创建好了,子线程的 RunLoop 需要主动创建
  • RunLoop 在第一次获取时创建,在线程结束时销毁

获取 RunLoop 对象

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

RunLoop相关类

  • Core Foundation 中关于 RunLoop 的5个类
    1. CFRunLoopRef
    2. CFRunLoopModeRef
    3. CFRunLoopSourceRef
    4. CFRunLoopTimerRef
    5. CFRunLoopObserveRef

注:RunLoop如果没有这些东西,会直接退出

RunLoop 应用

  • 常驻线程
  • NSTimer
  • 自动释放池
  • PerformSelector
  • ImageView 显示

1. 常驻线程

应用场景:经常在后台进行耗时操作,比如:监控联网状态,扫描沙盒等,不希望线程处理完事件就销毁,保持常驻状态。
第一种

// 开启
- (void)run
{
// addPort: 添加端口(就是source)forMode: 设置模式
    [[NSRunLoop currentRunLoop] addPort: [NSPort port] forMode: NSDefaultRunLoopMode];
// 启动RunLoop
    [[NSRunLoop currentRunLoop] run];

 /*
  //另外两种启动方式
    [NSDate distantFuture]:遥远的未来  这种写法跟上面的run是一个意思
    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    不设置模式
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate distantFuture]];
  */
}

// 退出当前线程
[NSThread exit];

2. NSTimer (最常见 RunLoop 使用)

- (void)timer
{
    NSTimer *timer = [NSTimer timerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
    // 定时器只运行在NSDefaultRunLoopMode下,一旦RunLoop进入其他模式,这个定时器就不会工作
    //    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];

    // 定时器只运行在UITrackingRunLoopMode下,一旦RunLoop进入其他模式,这个定时器就不会工作
    //    [[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];

    // 定时器会跑在标记为common modes的模式下
    // 标记为common modes的模式:UITrackingRunLoopMode和NSDefaultRunLoopMode兼容
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}
- (void)timer2
{
    // 调用了scheduledTimer返回的定时器,已经自动被添加到当前runLoop中,而且是NSDefaultRunLoopMode
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:YES];
 
    // 修改模式
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}

UITableView 滚动时模式由 NSDefaultRunLoopMode 进入 UITrackingRunLoopMode,NSTimer 不再响应。NSRunLoopCommonMode模式下两种模式都可运行。

3. 自动释放池

参见参考文章

main里面有个死循环就是RunLoop循环
目的:

  1. 保证程序不退出;
  2. 负责监听事件,触摸(有没有人摸我)、时钟、网络事件(回调);
  3. 如果没有时间发生,会让程序进入休眠状态;
  4. 五种模式,UI模式优先级最高,UI模式只能被触摸事件触发,保证高效。
  5. 一条线程的生命只能通过任务保住

子线程里面设置定时器,可以看出子线程里面RunLoop需要自己开启,主线程则默认已经开启。直接用while(true)并不能实现触发事件效果。线程的声明需要通过任务保住,所以要将RunLoop开启。
RunLoop是懒加载,只有第一次去拿才会创建。

RunLoop总结_第7张图片

总结一下


RunLoop总结_第8张图片

参考文章

https://blog.ibireme.com/2015/05/18/runloop/
深入理解RunLoop
解密-神秘的 RunLoop
(最全)RunLoop 原理+使用场景+面试总结

学习视频

Runloop视频 密码:ztaf
Runloop培训视频

你可能感兴趣的:(RunLoop总结)