想多瞭解下iOS的運行機制,因此搜了搜runloop的資料看看,發現看了好幾篇都沒有看懂這個runloop用來幹嗎的。說到runloop是用來作什麼的,只有一句話:oop
下來是Run Loop的使用場合:
1. 使用port或是自定義的input source來和其餘線程進行通訊
2. 在線程(非主線程)中使用timer
3. 使用 performSelector…系列(如performSelectorOnThread, …)
4. 使用線程執行週期性工做
spa
卻沒有地方針對每一個方面說一下,到底這四個方面是怎麼用的。其實我不是關心這四個功能怎麼實現,我關心的是在這些功能裏面,runloop起了什麼做用。.net
我很生氣,看到一片片文章人云亦云,這些人怎麼都不本身多思考一下?線程
個人思惟習慣是,對於一個新的待了解的東西,我須要先知道它是用來幹什麼的、它在什麼樣的環境下使用而且起到了什麼樣的做用,而後纔是去分析它的結構屬性,具體怎麼使用。首先沒有對一個東西的定位,怎麼去處理它的細節問題?code
查了一些資料,只瞭解了一點:orm
一、RunLoop本質上是一個消息處理的機制,它不斷的循環運行,判斷線程中是否有須要處理的消息。這個理解來源於有篇文章說的一個例子:手機上一個程序開啓,當你不去動它時,這個程序就好像死了同樣,可是隻要你觸碰一個按鈕,它就會立刻響應,就好像程序一直處於待命狀態。這就是主線程的runloop一直在運行,監測事件。blog
二、有了這個理解,接下來就會想runloop會監測哪些事件。當你知道了它監測哪些事件,也就知道了在什麼狀況下須要使用開啓runloop。回答這個問題就是上面藍色那段話。由於主線程的runloop是默認開啓的,因此咱們通常用到像:事件
[self performSelector:@selector(delay) withObject:nil afterDelay:1];這樣的方法,系統都會天然執行。但這個方法得以執行,實際須要靠主線程的runloop的,可是咱們很容易忽視了它。對於這個方法,文檔有很好的解釋:
This method sets up a timer to perform the aSelector message on the current thread’s run loop. The timer is configured to run in the default mode (NSDefaultRunLoopMode). When the timer fires, the thread attempts to dequeue the message from the run loop and perform the selector. It succeeds if the run loop is running and in the default mode; otherwise, the timer waits until the run loop is in the default mode.文檔
If you want the message to be dequeued when the run loop is in a mode other than the default mode, use the performSelector:withObject:afterDelay:inModes: method instead. If you are not sure whether the current thread is the main thread, you can use the performSelectorOnMainThread:withObject:waitUntilDone: or performSelectorOnMainThread:withObject:waitUntilDone:modes: method to guarantee that your selector executes on the main thread. To cancel a queued message, use the cancelPreviousPerformRequestsWithTarget: or cancelPreviousPerformRequestsWithTarget:selector:object: method.get
這個方法會構建一個計時器,把 aSelector message運行在當前線程的runloop上。這個計時器配置爲使用默認的模式運行。當計時器fires(NSTimer的fire方法是啓動計時器,不過這裏貌似是當計時器的時間到了,好比這裏延時1秒,應該是計時器開啓以後一秒)時,當前線程又會常識從runloop上面獲取message,而後執行方法。若是當前runloop是以默認模式運行就會成功。而後說明了若是不是使用默認模式、不肯定當前是否主線程等狀況下使用同類型的哪些其餘方法。 因此這個過程當中須要runloop作一箇中介,在調用performSelector時runloop會保存要調用的方法信息,而後在時間到了,當前線程會從runloop裏面獲取方法信息,而後調用。因此須要runloop的參與,須要開啓runloop。
關於文檔裏面的aSelector message,個人理解是,使用SEL來調用方法,不是直接調用方法,是發送消息給方法的調用者(target),讓它去執行方法。因此關鍵的東西是這個消息,這個消息至少應該保存方法的調用者(target)和方法自己的信息,可能還有參數。因此纔會有aSelector message「方法消息」這麼樣的詞,而後保存進runloop中的應該也是這麼樣一個消息。而runloop在它循環運行的過程當中,會不斷監測相似的消息,在特定的時機調用。
可能有不正確的地方,僅提供一種理解,歡迎指正。
關於其餘的輸入源,也就是第一種使用場合,能夠參考:這篇文章 的2.1.1輸入源的部分。