一、什么是runLoop

  1、说白了,runloop就是运行循环

  2、runloop,他是多线程的法宝

    通常来讲,一个线程一次只能执行一个任务,执行完之后就退出线程。但是,对于主线程是不能退出的,因此我们需要让主线程即使任务执行完毕,也可以继续等待接收事件而不退出,那么runloop就可以做到。

    但是非主线程通常来说就是为了执行某一任务的,执行完毕就需要归还资源,因此默认是不运行runloop的。

  3、每一个线程对应都有一个runloop,只是默认只有主线程的runloop是开启的,其他子线程的runloop是默认不启动的,若要启动需要程序员手动启动。

  

二、runloop作用

  1、保证程序不退出

  2、负责监听所有的事件(sources、observe、timer)(触摸、时钟、网络事件)

  3、runloop非常懒,有任务就处理,没有就睡眠

  4、runloop负责在一次循环中渲染UI

三、runloop模式

  NSRunLoopDefaultMode:App的默认Mode,通常主线程是在这个Mode下运行
  UITrackingRunLoopMode:处理UI事件的mode
  NSRunLoopCommonModes:这是一个占位用的Mode,不是一种真正的Mode(默认在NSRunLoopDefaultMode和UITrackingRunLoopMode这两种模式下
  UIInitializationRunLoopMode:在刚启动App时进入的第一个Mode,启动完成后不再使用
  GSEventReceiveRunLoopMode:接受系统事件的内部Mode,通常用不到

一个场景:加载多张高清大图时拖拽tableView,导致界面卡顿

  分析一:

    加载多张高清大图:需要加入runloop,在运行循环时渲染UI,进入UITrackingRunLoopMode模式

    拖拽tableView:需要加入runloop,在运行循环时处理触摸事件,进入UITrackingRunLoopMode模式

    加载多张高清大图,相当于runloop一次循环渲染了多张大图(多个任务),占用了这次循环的大部分时间,导致界面卡顿    

  解决方案:让runloop一次循环只渲染一张大图(只干一件事),定义观察者,每次循环添加一张图片进行渲染!

  代码以及实现已经有大神整理好了:https://blog.csdn.net/liyanjun201/article/details/79096289

以下是其他大神整理的关于runloop的资料 很全面  https://blog.csdn.net/qq_30513483/article/details/53373905

RunLoop是什么,有什么作用,如何获取?

  • 定义

    • RunLoop的实质是一个死循环,用于保证程序的持续运行,只有当程序退出的时候才会结束(由main函数开启主线程的RunLoop)
  • 作用
    • 保持程序的持续运行
    • 处理App中的各种事件(触摸、定时器、Selector事件)
    • 节省CPU资源,提高程序性能(该做事做事,没事做休息)
  • 获取方法
    • 使用NSRunLoop(面向对象)或者CFRunLoopRef(底层C语言)

RunLoop的原理

  • RunLoop开启一个循环事件,并接受输入事件,接受的事件来自两种不同的来源:

    • 输入源(input source)(传递异步事件)
    • 定时源(timer source)(传递同步事件)
  • RunLoop接收到消息后采用handlePort、customSrc、mySelector和timerFired等四个方法处理对应的事件
  • 当RunLoop没有接收到消息时,则进入休眠状态,以保持程序持续运行

RunLoop的原理

RunLoop接收几种输入源,系统默认定义了几种模式?

  • 输入源有两种

    • 基于端口的输入源(port)
    • 自定义的输入源(custom)
  • 系统定义的RunLoop模式有五种,最常用的有三种,如下所示:
    • NSDefaultRunLoopMode

      • 默认模式,主线程中默认是NSDefaultRunLoopMode
    • UITrackingRunLoopMode
      • 视图滚动模式,RunLoop会处于该模式下
    • NSRunLoopCommonModes
      • 并不是真正意义上的Mode,是一个占位用的“Mode”,默认包含了NSDefaultRunLoopMode和UITrackingRunLoopMode两种模式

RunLoop模式的原理和使用注意点?

  • 原理和注意点

    • 一个RunLoop包含若干个Mode,每个Mode又包含若干个Source、Observer、Timer(如下图所示)
    • 每次RunLoop启动,只能指定一个Mode,这个Mode被称为CurrentMode
    • 如果需要切换Mode,只能退出Loop,再重新指定一个Mode进入, 以使不同组之间的Source、Observer、Timer互不受影响

RunLoopMode

RunLoop和线程有什么关系

  • RunLoop与线程是一一对应的
  • 程序启动时,主线程默认会自己创建RunLoop,并设置为Default模式
  • 创建子线程时,必须获取当前线程的RunLoop并启动它

NSTimer和RunLoop的关系?

  • NSTimer需要添加到Runloop中, 才能执行的情况
  • NSTimer默认被添加到Runloop中, 直接执行的情况

NSTimer准确吗,如果不准确,如何设计一个准确的timer?

  • 不准确
  • 准确的Timer应该和当前线程的RunLoopMode保持一致

TableView/ScrollView/CollectionView滚动时为什么NSTimer会停止?

  • 一个RunLoop不能同时共存两个mode
  • 当滚动视图滚动时,当前RunLoop处于UITrackingRunLoopMode,
  • NSTimer的RunLoopMode和当前线程的RunLoopMode不一致,所以会停止
  • 解决方法:将timer的runloopMode改为UITrackingRunLoopMode或者NSRunLoopCommonModes

如果NSTimer在分线程中创建,会发生什么,应该注意什么?

  • NSTimer没有启动

    • 在主线程中,系统默认创建并启动主线程的runloop
    • 在分线程中,系统不会自动启动runloop,需要手动启动
  • 解决方法:
    • 启动分线程的runLoop

在异步线程中下载很多图片,如果失败了,该如何处理?请结合RunLoop来谈谈解决方案

  • 在异步线程中启动一个RunLoop重新发送网络请求,下载图片

如果程序启动就需要执行一个耗时操作,你会怎么做?

  • 开启一个异步的子线程,并启动它的RunLoop来执行该耗时操作

runloop与autoreleasepool的关系

如果在分线程中启动一个异步请求,会有什么问题?

判断其是否请求结束,如果未结束,要保持当前线程一直启动,直到结束

程序启动时,runloop是如何工作的?如果程序启动就需要执行一个耗时操作,你会怎么做?

程序启动时,系统默认创建并启动主线程的runloop,runloop会默认创建两个Observe来进行监听runloop的进出和睡眠,有事情的时候就去做,没事的休眠

(线程(创建)-->runloop将进入-->最高优先级OB创建释放池-->runloop将睡-->最低优先级OB销毁旧池创建新池-->runloop将退出-->最低优先级OB销毁新池-->线程(销毁))

线程刚创建时并没有runloop,如果你不主动去获取,那么一直都不会有。

耗时操作可以放在分线程中进行,结束后回到主线程

runloop 小记的更多相关文章

  1. RunLoop的知识小记

    RunLoop字面上的意思是,运行循环: 其基本作用:保持程序的持续运行: 处理App中的各种事件(比如:触摸事件.定时器事件.Selector事件) 节省CPU资源,提高程序性能:该做事时做事,该休 ...

  2. [原]Paste.deploy 与 WSGI, keystone 小记

    Paste.deploy 与 WSGI, keystone 小记 名词解释: Paste.deploy 是一个WSGI工具包,用于更方便的管理WSGI应用, 可以通过配置文件,将WSGI应用加载起来. ...

  3. RunLoop 总结:RunLoop的应用场景(一)

    参考资料 好的书籍都是值得反复看的,那好的文章,好的资料也值得我们反复看.我们在不同的阶段来相同的文章或资料或书籍都能有不同的收获,那它就是好文章,好书籍,好资料.关于iOS 中的RunLoop资料非 ...

  4. 我的runloop学习笔记

    前言:公司项目终于忙的差不多了,最近比较闲,想起叶大说过的iOS面试三把刀,GCD.runtime.runloop,runtime之前已经总结过了,GCD在另一篇博客里也做了一些小总结,今天准备把ru ...

  5. [tableView reloadData] 和 runloop

    需要[tableView reloadData]后需要立即获取tableview的cell.高度,或者需要滚动tableview,那么,直接在reloadData后执行代码是会有问题的. 断点调试感觉 ...

  6. RunLoop 总结:RunLoop的应用场景(二)

    上一篇讲了使用RunLoop保证子线程的长时间存活,而不是执行完任务后就立刻销毁的应用场景.这一篇就讲述一下RunLoop如何保证NSTimer在视图滑动时,依然能正常运转. 参考资料 好的书籍都是值 ...

  7. MySql 小记

    MySql  简单 小记 以备查看 1.sql概述 1.什么是sql? 2.sql发展过程? 3.sql标准与方言的关系? 4.常用数据库? 5.MySql数据库安装? 2.关键概念 表结构----- ...

  8. iOS多线程-RunLoop简介

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

  9. Git小记

    Git简~介 Git是一个分布式版本控制系统,其他的版本控制系统我只用过SVN,但用的时间不长.大家都知道,分布式的好处多多,而且分布式已经包含了集中式的几乎所有功能.Linus创造Git的传奇经历就 ...

随机推荐

  1. go string类型的特性

    参考文章: http://c.biancheng.net/view/36.html 1. 获取ascii类型字符的长度个数和获取utf8类型字符长度的个数 a. len("咪咪") ...

  2. Reactor系列(三)创建Flux,Mono(续)

    创建Mono 视频讲解:https://www.bilibili.com/video/av78944069/ FluxMonoTestCase.java package com.example.rea ...

  3. quartz报错 org.quartz.impl.StdSchedulerFactory.

    quartz任务执行报错 Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/LoggerFa ...

  4. PAT题目AC汇总(待补全)

    题目AC汇总 甲级AC PAT A1001 A+B Format (20 分) PAT A1002 A+B for Polynomials(25) PAT A1005 Spell It Right ( ...

  5. Photon Server 实现注册与登录(五) --- 服务端、客户端完整代码

    客户端代码:https://github.com/fotocj007/PhotonDemo_Client 服务端代码:https://github.com/fotocj007/PhotonDemo_s ...

  6. Devexpress xaf用代码打开菜单(Navigation Item)

    第一种:ViewController继承WindowController public abstract class MyWindowController : WindowController { p ...

  7. Django中ORM常用字段及字段参数

    Object Relational Mapping(ORM) ORM介绍 ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据 ...

  8. javaIO——BufferedReader效率测试实践

    上一篇刚刚学习了 BufferedReader ,想着来验证一下 BufferedReader 的缓冲到底能带来多大的性能提升,于是拷贝了一个100M 左右的日志文件放到本地,测试一下使用 Buffe ...

  9. 使用 SQL的 for xml path来进行字符串拼接

    本篇主要讲怎么利用SQL的FOR XML PATH 参数来进行字符串拼接,FOR XML PATH的用法很简单,它会以xml文件的形式来返回数据. 我的讲解步骤: 1:构造初始数据 2:提出问题 3: ...

  10. spark2.0 DataSet操作的一些问题记录

    随着新版本的Spark已经逐渐稳定,最近拟将原有框架升级到spark 2.0.还是比较兴奋的,特别是SQL的速度真的快了许多.. 然而,在其中一个操作时却卡住了.主要是dataframe.map操作, ...