iOS知识点整理-#RunLoop#

iOS学习笔记整理-纸上得来终觉浅 写成文档不怕丢:-D

RunLoop In Cocoa

RunLoop 顾名思义,可以通俗的将之理解为一个无限Run的循环(loop),得益于这种机制,OC可以捕获程序内的事件并响应。

当有持续的异步任务需求时,我们会创建一个独立的生命周期可控的线程。RunLoop就是控制线程生命周期并接收事件进行处理的机制。

RunLoop是iOS事件响应与任务处理最核心的机制,它贯穿iOS整个系统。 在Fundation框架下我们平时使用的的是NSRunloop类,他是Core Fundation框架下CFRunloop类的上层封装。

CFRunloop构成

CFRunloop和Thread是一一对应的关系,每一个CFRunloop对象能且仅能运行在一种CFRunloopMode下,而CFrunloopMode内部又是由若干个CFRunloopSource、CFRunloopTimer、CFRunloopObserver对象以Array的形式组成的。

CFRunloopMode

  • Runloop在同一时段下能且只能运行在一种Mode下;
  • 想要更换当前mode,则需要停止当前loop,重启新的loop;
  • mode是iOS App滑动顺畅的关键
  • 开发者可以自定义mode

CFRunloopMode类型

  • NSDefaultRunloopMode 默认状态,空闲状态
  • UITrackingRunloopMode 滑动ScrollView时的状态
  • UIInitializationRunloopMode (私有状态)app启动时所处的状态
  • NSRunloopCommentMode 自定义状态,一般是上面状态的集合
  • GSEventReceiveRunLoopMode:接受系统内部事件,通常用不到

RunLoop可以通过[acceptInputForMode:beforeDate:]和[runMode:beforeDate:]来指定在一段时间内的运行模式。如果不指定的话,RunLoop默认会运行在Default下(不断重复调用runMode:NSDefaultRunLoopMode beforDate:)

在主线程启动一个计时器Timer,然后拖动UITableView或者UIScrollView,计时器不执行。这是因为,为了更好的用户体验,在主线程中Event tracking模式的优先级最高。在用户拖动控件时,主线程的Run Loop是运行在Event tracking Mode下,而创建的Timer是默认关联为Default Mode,因此系统不会立即执行Default Mode下接收的事件。 解决方法:

NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval:1.0
                                                   target:self
                                                 selector:@selector(timerFireMethod:)
                                                 userInfo:nil
                                                  repeats:YES];
                                                  
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; 
//或 
[[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];

[timer fire];
复制代码

RunLoopTimer

就是我们所理解的Timer计时器

RunloopSource

source可以理解为Runloop的数据抽象源(protocol); Runloop定义了两个version的Source:

  • source0:用于处理APP内部事件,app自己负责管理/触发,常见的有UIEvent、CFSocket类等;
  • source1:由Runloop和系统内核管理,mach Port驱动,常见的有CFMachPort、CFMessagePort等;

CFRunloopObserver

该对象用于向外部报告runloop当前状态的更改,框架中,很多机制都是由RunloopObserver触发的,比如CAAnimation动画。

CFrunloopObserver对外报告的状态枚举CF_OPTIONS共有6中,分别是

  • 1 进入loop
  • 2 准备Timer
  • 3 准备执行Obsever
  • 4 准备休眠
  • 5 休眠结束将要唤醒
  • 6 退出loop

RunLoopObserver与Autorelease Pool的关系

UIKit 通过 RunLoopObserver 在 RunLoop 两次 Sleep 间对 Autorelease Pool 进行 Pop 和 Push 将这次 Loop 中产生的 Autorelease 对象释放。

Runloop的挂起与唤醒

指定用于唤醒的 mach_port 端口调用 mach_msg 监听唤醒端口,被唤醒前系统内核将这个线程挂起,停留在 mach_msg_trap状态。 由另一个线程向内核发送这个端口的msg后,trap状态被唤醒,RunLoop继续工作。

RunLoop支持的消息Events

1 支持接收处理输入源(Input Source)事件,包括:

  • 系统的Mach Port事件,是一种通讯事件
  • 自定义输入事件

2 支持接受处理定时源(Timer)事件。

上图可以看出,Runloop必须添加input sources或 Timer sources用于保持监听循环,否则调用[runloop run]会直接返回,而不会进入循环让线程长驻。

因为如果没有添加任何输入源事件或Timer事件,线程会一直在无限循环空转中,会一直占用CPU时间片,没有实现资源的合理分配。 没有while循环且没有添加任何输入源或Timer的线程,线程会直接完成,被系统回收。

Run Loop主要有以下三个应用场景

  • 维护线程的生命周期,让线程不自动退出
  • 创建常驻线程,执行一些会一直存在的任务
  • 在一定时间内监听某种事件,或执行某种任务的线程

AFNetworking中RunLoop的创建

+ (void)networkRequestThreadEntryPoint:(id)__unused object {
    @autoreleasepool {
        [[NSThread currentThread] setName:@"AFNetworking"];

        NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
         // 这里主要是监听某个 port,目的是让这个 Thread 不会回收
        [runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode]; 
        [runLoop run];
    }
}

+ (NSThread *)networkRequestThread {
    static NSThread *_networkRequestThread = nil;
    static dispatch_once_t oncePredicate;
    dispatch_once(&oncePredicate, ^{
        _networkRequestThread =
        [[NSThread alloc] initWithTarget:self
                                selector:@selector(networkRequestThreadEntryPoint:)
                                  object:nil];
        [_networkRequestThread start];
    });
    return _networkRequestThread;
}
复制代码
weixin073智慧旅游平台开发微信小程序+ssm后端毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
python017基于Python贫困生资助管理系统带vue前后端分离毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值