多線程
NSTheard :alloc init 方法創建線程 。
start 方法啟動線程 。然后系統會管理線程的生命 。當對應的方法執行完畢之后 ,線程會自動銷毀 。
[NSTheard isMainTheard] 會監測包含的方法是不是在主線程中。
performSelectorInBackground:(SEL) withobject:(id)
是隱式創建線程 。
主線程阻塞 :
preformSelectorInMainTheard withObject waitUnitDone:(BOOL)
最后的bool值就是 ,是否要在執行完對應的方法之前 ,阻塞主線程 。
線程的狀態
start 以后,線程就是Runnable狀態。 放到了cpu調度池中等待cpu調用 。當cpu調度了這個線程以后,就是運行狀態running 。然后執行一段時間,cpu切換了別的線程 。就又回到等待就緒狀態Runnable
當調用了sleep/等待同步鎖操作后 ,線程就在阻塞狀態blocked
阻塞線程
+(void)sleepUnitilDate:(NSDate *)date
+(void)sleepForTimeInterval:(NSTimeInterval*)ti
強制退出線程
+(void)exit
多線程的安全問題 :搶占資源 線程鎖
互斥鎖 :@synchornized(鎖對象)
注意:鎖對象要是同一個 ,才能對各個線程紀錄正確的鎖狀態 。
加鎖了 ,就會造成線程同步 。相當于一個同步線程隊列 。
原子和非原子
原子:atomic 默認就為setter 方法加鎖 。默認就是線程安全的 。注意:屬性默認就是atomic
線程間通信
-(void)performSelectorOnMainThread:(SEL) withobject :(id) waitUnitilDone:(BOOL);
-(void)performSelector:(SEL) onThread:(NSThread) withObject:(id) waitUntilDone:(BOOL)
GCD
使用步驟:
- 定制任務:確定子線程需要做什么事情
- 將任務添加到隊列中:GCD會自動將隊列中的任務取出,放到對應的線程中去執行。
- 任務的取出遵循FIFO原則:先進先出 ,后進后出 。
GCD的兩個創建任務的函數 :
dispatch_async(dispatch_queue_t queue, ^(void)block) :異步 可以開啟新的線程
dispatch_sync(dispatch_queue_t queue, ^(void)block) :同步 意思是和外邊的代碼在同一個線程中 。不具備開啟新線程的能力
隊列類型
- 并發隊列(Concurrent dispatch queue)
- 串行隊列 (Serial dispatch queue)
- 創建一個并發隊列:
類型包括兩種 :dispatch_queue_t queue = dispatch_queue_create(名字 ,隊列類型)
- 1 DISPATCH_QUEUE_CONCURRENT (并發)
- 2DISPATCH_QUEUE_SERIAL (串行)
創建好了,只要把任務加入隊列中就可以了 。創建線程,開啟,銷毀等等都不需要管。
系統默認是提供了全局的并發隊列 。不需要手動創建 。
dispatch_get_global_queue(優先級 ,一個以后需要的參數 現在默認填0)
優先級 :DISPATCH_QUEUE_PRIORITY_(BACKGROUD(最低)/DEFAULT/HIGH/LOW)
主隊列:系統提供的串行隊列 放到主隊列中的任務都會在主線程中執行 。dispatch_get_main_queue()
在這個時候 ,異步函數也不會創建新的線程 ,只能在主線程中執行 。
異步+串行隊列 。
不管添加了幾個任務 。都只會創建一個子線程 ,然后串行,一個一個的挨個完成 。
同步函數+主隊列 。
會卡死。 注意:同步函數 ,馬上就需要執行 ,并不會等隊列所在的函數執行完再執行 。 異步函數,會等外邊的大函數先執行完,再執行隊列中的異步任務 。
GCD函數--阻隔函數
dispatch_berrier_async()
在異步的并發隊列中 ,會先執行他前面的任務 ,然后執行他本身的任務 ,最后才執行他后邊的任務 。(注意 ,在系統的全局隊列中不管用)只能自己創建并發隊列 。
宏定義
當有多行的時候,需要換行 ,用\連接 。
當要在后邊拼接文字的時候 ##