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不动了.所以当你面试的时候不要说主线程没了子线程也不会有这种话.

 

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

 

 

 




posted @ 2017-11-23 16:59  港吧休  阅读(2080)  评论(0编辑  收藏  举报