1.異步執(zhí)行
dispatch_async(dispatch_get_main_queue(), ^{
//打算執(zhí)行的任務(wù)
});
dispatch_async:表示異步執(zhí)行 不用等待里面的代碼執(zhí)行結(jié)束就可以往下執(zhí)行
dispatch_get_main_queue():表示獲取主線程
2.Dispatch Queue 種類
Serial Dispatch Queue:等待現(xiàn)在執(zhí)行中處理結(jié)束才能執(zhí)行其他任務(wù) //串行
Concuerrent Dispatch Queue:不等待現(xiàn)在執(zhí)行中處理結(jié)束就可以執(zhí)行其他任務(wù)? //并行
多個線程更新相同資源時導(dǎo)致數(shù)據(jù)競爭時使用Serial Dispatch Queue 來保證數(shù)據(jù)安全
dispatch_queue_t myqueue1 = dispatch_queue_create("com.GCD.myqueue1", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(myqueue1, ^{
NSLog(@"執(zhí)行的任務(wù)");
});
3.Main Dispatch Queue /Global Dispatch Queue 系統(tǒng)自帶線程
這倆個是系統(tǒng)提供給我們使用的Dispatch Queue,不用我們?nèi)ヌ匾鈩?chuàng)建了
Main Dispatch Queue : 主線程? 因為主線程只有一個所以是Serial Dispatch Queue? 像UI的刷新必須在主線程中進(jìn)行
Global Dispatch Queue : 是所有程序都能夠使用的Concuerrent Dispatch Queue雹食,另外Global Dispatch Queue有四個執(zhí)行優(yōu)先級:
高優(yōu)先級(High Priority)
默認(rèn)優(yōu)先級(Default Priority)
低優(yōu)先級(Low Priority)
后臺優(yōu)先級(Background Priority)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//可并行執(zhí)行的處理
});
在向Global Dispatch Queue追加處理時霞篡,應(yīng)選擇與處理內(nèi)容對應(yīng)執(zhí)行優(yōu)先級的Global Dispatch Queue
4.dispatch_set_target_queue 改變線程優(yōu)先級
dispatch_queue_create函數(shù)生成的Dispatch Queue不管是Serial Dispatch Queue還是Concuerrent Dispatch Queue窥岩,都使用與默認(rèn)優(yōu)先級Global Dispatch Queue相同執(zhí)行優(yōu)先級的線程氛驮,而變更優(yōu)先級就需要使用到dispatch_set_target_queue
dispatch_queue_t mySerialQueue = dispatch_queue_create("com.gcd.mySerialQueue", NULL);
dispatch_queue_t globalQueueBackground =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
dispatch_set_target_queue(mySerialQueue, globalQueueBackground);
5.dispatch_after 延遲執(zhí)行
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 3ull * NSEC_PER_SEC);
dispatch_after(time, dispatch_ge? t_main_queue(), ^{
//延遲3秒執(zhí)行的任務(wù)
});
SEC:表示秒
MSEC:毫秒
ull 是C語言中的數(shù)值字面量刹淌,是顯示表明類型時使用的字符串(表示"unsigned long long")
6.Dispatch Group 多個處理全部結(jié)束后想執(zhí)行結(jié)束處理
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
//任務(wù)1
});
dispatch_group_async(group, queue, ^{
//任務(wù)2
});
dispatch_group_async(group, queue, ^{
//任務(wù)3
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
//等待上面三個任務(wù)全部執(zhí)行完畢后祟偷,執(zhí)行結(jié)束處理
});
7.dispatch_barrier_async? 進(jìn)行數(shù)據(jù)庫操作時避免數(shù)據(jù)競爭
寫入數(shù)據(jù)不可與讀取數(shù)據(jù)以及其他寫入操作并行操作彩郊,否則就會發(fā)生問題
dispatch_queue_t queue = dispatch_queue_create("com.gcd.ForBarrier", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{? ? NSLog(@"讀取操作");? });
dispatch_async(queue, ^{? ? NSLog(@"讀取操作");? });
dispatch_async(queue, ^{? ? NSLog(@"讀取操作");? });
dispatch_async(queue, ^{? ? NSLog(@"讀取操作");? });
dispatch_barrier_async(queue, ^{ NSLog(@"寫入操作"); });? //此時不可以讀取數(shù)據(jù)? 可以把其當(dāng)做一個Serial Dispatch Queue
dispatch_async(queue, ^{? ? NSLog(@"讀取操作");? });
dispatch_async(queue, ^{? ? NSLog(@"讀取操作");? });
dispatch_async(queue, ^{? ? NSLog(@"讀取操作");? });
dispatch_async(queue, ^{? ? NSLog(@"讀取操作");? });
8.dispatch_sync 同步
既然有async 那么就有sync
使用場景:在主線程中使用其他線程進(jìn)行處理前弯,處理結(jié)束后需要立即使用所得到的結(jié)果
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_sync(queue, ^{
//處理任務(wù)
});
正因為其使用簡單,所以也容易引起問題秫逝,死鎖
如果在主線程執(zhí)行以下代碼就會死鎖
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_sync(queue, ^{
//執(zhí)行任務(wù)
});
該代碼在主線程中執(zhí)行指定block恕出,并等待其執(zhí)行結(jié)束,而其實在主線程中正在執(zhí)行這些代碼筷登,所以無法追加到主線程的block
9.dispatch_apply
按指定的次數(shù)將指定的block追加到指定的線程中剃根,并等待全部處理執(zhí)行結(jié)束
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_apply(10, queue, ^(size_t index) {
NSLog(@"%zu",index);
});
NSLog(@"Done");
執(zhí)行結(jié)果:
6
4
3
7
5
2
1
9
0
8
Done //Done肯定在最后 因為要等待執(zhí)行結(jié)束
推薦在dispatch_async中非同步執(zhí)行dispatch_apply 函數(shù)
10.dispatch_suspend / dispatch_resume 掛起/恢復(fù)
dispatch_suspend(queue);
dispatch_resume(queue);
這些函數(shù)對已經(jīng)執(zhí)行的處理沒有影響哩盲,掛起后前方,追加到線程中但尚未執(zhí)行的處理在此之后停止執(zhí)行狈醉,而恢復(fù)則使得這些處理能夠繼續(xù)執(zhí)行
11.dispatch_once 應(yīng)用程序運(yùn)行期間只執(zhí)行一次
static dispatch_once_t pred;
dispatch_once(&pred, ^{
//進(jìn)行初始化
});
該代碼即使在多線程環(huán)境中執(zhí)行,也可保證百分百安全
12.Dispatch I/O
在讀取較大文件時惠险,如果將文件分成合適的大小并使用Global Dispatch Queue 并列讀取的話苗傅,速度會快上許多。