GCD學(xué)習(xí)三
常用函數(shù):
dispatch_set_target_queue
dispatch_after
dispatch_group
dispatch_barrier_async
dispatch_sync
dispatch_apply
dispatch_suspend/dispatch_resume
dispatch_semaphore
dispatch_once
dispatch I/O
dispatch_set_target_queue
1.變更優(yōu)先級
2.使多個同步隊列只執(zhí)行一個。
1、我們用dispatch_queue_create創(chuàng)建的隊列,最后都變成global dispatch queue的默認(rèn)級別。如果我們要變更優(yōu)先級,就可以使用dispatch_set_target_queue函數(shù)
上代碼:
// 創(chuàng)建一般隊列
dispatch_queue_t mySerialDispatchQueue = dispatch _queue_create("com.example.gcd.MySerialDispatchQueue",NULL);
// 創(chuàng)建后臺隊列
dispatch_queue_t globalDispatchQueueBackground = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,0);
// 一般隊列轉(zhuǎn)換成后臺隊列dispatch_set_target_queue(mySerialDispatchQueue,globalDispatchQueueBackground);
注意:第一個參數(shù)最好用自定義的隊列,不要用系統(tǒng)的隊列,可能會出錯。
2、如果多個Serial Dispatch Queue用dispatch_set_target_queue函數(shù)指定某個Serial Dispatch Queue,那么原本應(yīng)該執(zhí)行多個Serial Dispatch Queue,現(xiàn)在在目標(biāo)Serial Dispatch Queue上只能執(zhí)行一個處理??梢苑乐共⑿刑幚怼?br>
dispatch_after
1、延遲執(zhí)行
注意:是指在x秒后將指定的block添加到Main Dispatch Queue中,不是直接執(zhí)行block里面代碼。
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW,3ull*NSEC_PER_SEC);
dispatch_after(time,dispatch_get_main_queue(),^{
??? //執(zhí)行代碼
});
Dispatch Group
1、如果我們使用串行隊列便可以在一個隊列執(zhí)行完后執(zhí)行下一個,但是如果是并行隊列呢?
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
dispatch_group_t group = dispatch_group_create();
// 并行隊列放到group中
dispatch_group_async(group,queue,^{NSLog(@"blk1");});
dispatch_group_async(group,queue,^{NSLog(@"blk2");});
dispatch_group_async(group,queue,^{NSLog(@"blk3");});
//第一種方式 執(zhí)行完成通知該組
dispatch_group_notify(group,dispatch_get_main_queue(),^{NSLog(@"done");});
// 第二種方式 等待
disptach_group_wait(group,DISPATCH_TIME_FOREVER);// 第二個參數(shù)是時間
dispatch_barrier_async
現(xiàn)在有一種情形,對一個數(shù)據(jù)庫讀取和寫入操作,要如何實現(xiàn)。
dispatch_queue_t queue = dispatch_queue_create("name",DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue,blk1_for_reading);
dispatch_barrier_async(queue,blk_for_writing);
dispatch_async(queue,blk1_for_reading);
?dispatch_async(queue,blk1_for_reading);

dispatch_sync
dispatch_sync函數(shù)等待執(zhí)行完成才執(zhí)行下一個,易發(fā)生死鎖。
dispatch_async函數(shù)不做任何等待
dispatch_apply
dispatch_apply函數(shù)是dispatch_sync函數(shù)和dispatch_group函數(shù)的聯(lián)合api.能夠按照指定的次數(shù)將指定的block添加到指定的Dispatch Queue中,并等待全部執(zhí)行結(jié)束。
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRORITY_DEFAULT,0);
dispatch_apply(5,queue,^(size_t index){
NSLog(@"%zu",index);
});
NSLog(@"done");
輸出結(jié)果:2 1 3 0 4 done
是等到里面全部執(zhí)行完成,再執(zhí)行done
dispatch_suspend/dispatch_resume
dispatch_suspend 函數(shù)掛起指定的Dispatch Queue
dispatch_suspend(queue);
dispatch_resume函數(shù)恢復(fù)指定的Dispatch Queue
dispatch_resume(queue);
注意:這些函數(shù)對已經(jīng)執(zhí)行的處理沒有影響。掛起后,追加到Dispatch Queue中但尚未執(zhí)行的處理在此之后停止執(zhí)行。而恢復(fù)則使得這些處理能夠繼續(xù)。
Dispatch Semaphore
雖然我們可以通過Serial Dispatch Queue 和 Dispatch_barrier_async函數(shù)可以避免資源競爭。但是有更好的辦法處理這類問題。
在GCD中有三個函數(shù)是semaphore的操作,分別是:
dispatch_semaphore_create 創(chuàng)建一個semaphore,初始化一個值
dispatch_semaphore_signal 發(fā)送一個信號,該值+1
dispatch_semaphore_wait 等待信號,該值為0->執(zhí)行,否則等待并-1
創(chuàng)建Dispatch Semaphore
dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
等待Dispatch_semaphore_wait
dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);
發(fā)送信號Dispatch_semaphore_signal
dispatch_semaphore_signal(semaphore);
dispatch_group_t group = dispatch_group_create();
dispatch_semaphore_t?semaphore?=?dispatch_semaphore_create(10);
dispatch_queue_t?queue?=?dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,?0);
for(inti?=?0;?i?<?100;?i++)
{
dispatch_semaphore_wait(semaphore,?DISPATCH_TIME_FOREVER);
dispatch_group_async(group,?queue,?^{
NSLog(@"%i",i);
sleep(2);
dispatch_semaphore_signal(semaphore);
});
}
dispatch_group_wait(group,?DISPATCH_TIME_FOREVER);
dispatch_release(group);
dispatch_release(semaphore);
dispatch_once
該函數(shù)保證在應(yīng)用程序執(zhí)行中只執(zhí)行一次,能夠保證在多核編程中保證安全。
static dispatch_once_t pred;
dispatch_once(&pred,^{
?//執(zhí)行操作
});
Dispatch I/O
能夠?qū)崿F(xiàn)一次性使用多個線程更快的并列讀取