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不動了.所以當你面試的時候不要說主線程沒了子線程也不會有這種話.

 

新手分享!!!他說:想要成為大牛,首先要學會分享,把你學到的東西分享給別人,利己利人.如果你學到東西了,那把它分享給你身邊的朋友吧.

 

 

 





免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM