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