zoukankan      html  css  js  c++  java
  • Runloop详解面试题(面试必备NSTimer)

    什么是 Runloop?

    • 从字面上讲就是运行循环。
    • 它内部就是do-while循环,在这个循环内部不断地处理各种任务。说通俗来说就是一个死循环.
    • 一个线程对应一个RunLoop,主线程的RunLoop默认已经启动,子线程的RunLoop得手动启动(调用run方法)
    • RunLoop只能选择一个Mode启动,如果当前Mode中没有任何Source(Sources0、Sources1)、Timer,那么就直接退出RunLoop

    • 基本的作用就是保持程序的持续运行,处理app中的各种事件。通过runloop,有事运行,没事就休息,可以节省cpu资源,提高程序性能。

     Runloop 初识

         首先我们知道新建一个项目之后他的启动是Main函数,那么我们首先往UIApplicationMain函数的前后分别加入一行NSlog,如下图

    运行之后我们看到,控制台只输出了 "这里" 并没有输入"here",这是因为在UIApplicationMain上开启了主线程的Runloop循环,也就是说在那里有一个死循环,所以下边的"here"不会输出.那么问题来了,为什么要开启这个Runloop循环,开启这个循环有什么用?

    1,保证主线程的生命,保证当前线程不退出,这是必不可缺少的一部分,如果程序一运行,主线程没了,UIKit都没了那就没必要继续开发了....

    2,负责监听事件,网络事件,触摸事件时钟等等.

    Runloop 入门

    经常会有人在面试中被问到:NStimer准吗?谈谈你的看法?如果不准该怎样实现一个精确的NSTimer?  实际上面试官是在看你懂不懂Runloop.

    这时候你该这样回答:

    1,无论是单次执行的NSTimer还是重复执行的NSTimer都不是准时的

    2这与当前NSTimer所处的线程有很大的关系,如果NSTimer当前所处的线程正在进行大数据处理(假设为一个大循环),NSTimer本次执行会等到这个大数据处理完毕之后才会继续执行。这期间有可能会错过很多次NSTimer的循环周期,但是NSTimer并不会将前面错过的执行次数在后面都执行一遍,而是继续执行后面的循环,也就是在一个循环周期内只会执行一次循环。

    所以我们要习惯把NSTimer放在Runloop中去执行,       [NSRunLoop currentRunLoop];//获取当前线程的Runloop      [NSRunLoop mainRunLoop];//获取主线程的Runloop  见下图

      

    这里需要注意的是forMode 提供的参数.我们根据实例来了解这个mode到底有什么用,首先往屏幕上放一个textView,运行程序后,控制器在不停的运行timer(也就是不停的去执行Method方法).  但是当我们拖拽textView的时候,Metiod方法停止运行了,相信大家在平时开发中也遇到过这样的情况,那么这是为什么呢?

    答:记住一条规则,Runloop处理事件的时候,UI优先,天大地大UI最大. (这就合理的解释了为什么当我们拖动textView的时候timer方法不执行了)这也是一种NSTimer不准的情况

    那么怎么在拖动的时候使timer方法继续执行呢?除了GCD之外我们了解一下Runloop.

    上图我们看到forMode是NSDefault模式的,也就是默认模式的,mode一共有五种,我们只需要知道其中三种即可

    • NSDefalutRunLoopMode      默认状态.优先处理UI模式下的事件
    • UITrackingRunLoopMode     UI模式,将timer放在UI模式下,但是当停止拖拽textView时,timer方法停止了.(只能被UI事件唤醒)
    • NSRunLoopCommonModes     默认包括上面两种,也就是说,兼容两种的,也是通用的.
    到这里我们就解决了这一问题,在这给大家科普一条,UI为什么要放在主线程执行,我们开发的项目首先要用户体验好,如果不在主线程中(不优先),那么它就会涉及到资源抢夺,我们还要给他上锁为了安全性,但是上锁又会影响性能,那么我们的用户体验将会特别差.所以UI操作永远不会涉及到多线程.所以UIKit要放在主线程上.

    还有一个误区,很多人说,主线程没有了,子线程就没了,整个程序就没了.当然对于用户来说,主线程没了整个项目就没了,因为UI不动了.但对于开发者来说,主线程没了,子线程不一定没了.相对于系统来说,主线程也只是一条子线程而已.下边附案例.

     

    viewdidload中开辟子线程,将定时器放在子线程中,当点击屏幕时退出主线程.此时看控制台,子线程没有挂,还在输出. 只是UI不动了.所以当你面试的时候不要说主线程没了子线程也不会有这种话.

    新手分享!!!他说:想要成为大牛,首先要学会分享,把你学到的东西分享给别人,利己利人.如果你学到东西了,那把它分享给你身边的朋友吧.




  • 相关阅读:
    系统并发报too much open files 错误
    plsql 安装Some Oracle Net versions cannot connect from a path with parentheses
    mysql登录报错
    web.xml配置文件详解之一servlet配置
    hibernate createQuery查询传递参数的两种方式
    mysql登录连接远程数据库命令行
    java 项目打包部署 过程
    flex ArrayCollection的新增与删除的同步
    加大eclipse以及jvm的内存
    2017 八月 UFED Series Releases 系列 6.3 重大更新发布
  • 原文地址:https://www.cnblogs.com/baxiu/p/7884194.html
Copyright © 2011-2022 走看看