一般來講,一個線程一次只能執行一個任務,執行完畢后線程就會退出,如果我們需要一個機制讓線程能隨時處理時間但並不退出,通常的代碼邏輯是這樣:
這就是 Event Loop框架。
runloop實際上就是一個管理其需要處理的事件和消息的對象,並提供了一個入口函數來執行上面Event loop的邏輯。線程執行了這個函數之后,就會一直處於這個函數內部“接受消息-》等待-》處理”的循環中,知道這個循環結束(例如傳入quite消息),函數返回。
在OSX和iOS系統中,提供了兩個這樣的對象:NSRunLoop和CFRunLoopRef。
CFRunLoopRef是基於CoreFoundation框架內的,它提供了純C函數的API,所有這些API都是線程安全的。
NSRunLoop是基於CFRunLoopRef的封裝,提供面向對象的API,但是這些API不是線程安全的。
RunLoop和線程的關系:iOS開發中有兩個線程對象-pthread_t和NSThread。pthread_tNSThread是一一對應的。比如你可以通過pthrea_main_thread_np()或者[NSThread currentThread]來獲取當前線程。CFRunLoop是基於pthread來管理的。
蘋果不允許直接創建RunLoop,但是提供了兩個自動獲取的函數:CFRunLoopGetMain()和CGRunLoopGetCurrent()。這兩個函數的內部邏輯大概為:
線程和RunLoop之間是一一對應的,其關系是保存在一個全局的Dictionary里。線程剛創建時並沒有RunLoop,如果你不主動獲取,它一直都不會有。runloop的創建是發生在第一次獲取的時候,銷毀時在線程結束時。你只能在一個線程的內部獲取其RunLoop(主線程除外)。
Event驅動 主體就是一個死循環,沒事-休眠,有事-喚醒-執行
runloop:用於結局
1、使程序一直運行並接受用戶輸入
2、決定程序在何時應該處理哪些Event
3、調用解耦(Message Queue)
4、節省cpu時間
setNeedsLayout/setNeedsDisplay主動跟跟新UI。
iOS程序入口在int main函數,main函數內部會rentun ,一旦return就會結束程序,所以內部有個mainrunloop一種在運行,不會造成return,很多crash都是因為runloop不執行了就return了造成程序無法執行下去。
如圖,程序執行的時候不會執行nslog因為mainRunLoop在運行,不會ruturn一旦ruturn程序會退出。
mainRunLoop在一直執行,隨時喚醒處理事件,如果沒有runloop就不能實現隨時處理事件。
foundation中的NSRunLoop對象是通過Core Foundation框架的CFRunLoopRef封裝而來,提供的api比較少。cfrunloopref用的比較多。
子線程的runloop默認關閉,第一次獲取的時候才創建,有時候用不到浪費資源。runloop有資源才不會銷毀,沒資源會自定銷毀。
API里面NSTimer 是木有暫停繼續的方法的,只有fire和invalidate,前者是開工的意思,后者是廢掉的意思
在這種場景:要獲取事件(例如button按下之前需要處理,但是又不知道什么時候按下去),用runloop監聽runloop的狀態,喚醒了就說明按鈕按下去了。
監聽各個狀態在某個狀態中處理事件。
以下是個各種狀態
performSelector:......也是source。
主線程的runloop默認開啟,子線程的runloop默認不開啟,所以timer在子線程中是不會執行的,需要手動開啟runloop。手動開runloop需要runloop中添加資源,沒有資源的runloop會自動關閉。
runloop應用: runloop默認是不開啟的,在線程中第一次獲取的時候創建,run開啟。
1、Timer
2、UIImageView滑動不加載,runloop DefaultMode才加載。
3、PerformSelect
4、常駐線程:讓子線程常駐,需要讓他的runloop運行起來,那么mode種需要有source,在里買呢添加一個NSPort就行。
進程就是每個應用程序運行就會有一個進程,各應用間進程彼此獨立,進程依靠線程執行任務,每個進程至少有一個線程,線程中任務的執行是串行的,如果要在1個線程中執行多個任務,那么只能一個一個地按順序執行這些任務,也就是說,在同一時間內,1個線程只能執行1個任務。
線程中執行任務只能串行,但是線程可以並發執行。 同一時間,CPU只能處理1條線程,只有1條線程在工作(執行),多線程並發(同時)執行,其實是CPU快速地在多條線程之間調度(切換),如果CPU調度線程的時間足夠快,就造成了多線程並發執行的假象
思考:如果線程非常非常多,會發生什么情況?
CPU會在N多線程之間調度,CPU會累死,消耗大量的CPU資源,每條線程被調度執行的頻次會降低(線程的執行效率降低)。
多線程的優點
能適當提高程序的執行效率
能適當提高資源利用率(CPU、內存利用率)
多線程的缺點
開啟線程需要占用一定的內存空間(默認情況下,主線程占用1M,子線程占用512KB),如果開啟大量的線程,會占用大量的內存空間,降低程序的性能
線程越多,CPU在調度線程上的開銷就越大
程序設計更加復雜:比如線程之間的通信、多線程的數據共享
5、自動釋放池