線程就像是在程序運(yùn)行時(shí)又另開一條道路去做一些耗時(shí)的操作,不能讓所有的操作都堵在主線程那條路上劫映,這樣就像北京的堵車一樣壹将,體驗(yàn)非常不好。隊(duì)列就相當(dāng)于你修的單行路還是多行路
1.dispatch_queue_t
這個(gè)類就像是創(chuàng)建的道路的樣式
通過這個(gè)方法來創(chuàng)建一條新的道路,這個(gè)方法需要傳2個(gè)參數(shù)袱饭,第一個(gè)參數(shù)是為隊(duì)列添加一個(gè)唯一標(biāo)識(shí)川无,第二個(gè)參數(shù)是這個(gè)隊(duì)列的屬性:
DISPATCH_QUEUE_SERIAL(串行(單行道)for Null也是串行)
DISPATCH_QUEUE_CONCURRENT(并行(多行道))
dispatch_queue_create(const char *_Nullable label,
dispatch_queue_attr_t _Nullable attr);
串行就是所有加入隊(duì)列的操作就是依次執(zhí)行,看代碼效果吧:
//串行隊(duì)列
dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
//加入倆個(gè)異步操作
dispatch_async(queue, ^{
for(int i=0;i<5;i++ ){
NSLog(@" 1當(dāng)前線程 %@",[NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for(int i=0;i<5;i++ ){
NSLog(@" 2當(dāng)前線程 %@",[NSThread currentThread]);
}
});
看下結(jié)果,可以看出來是依次執(zhí)行的先把上一個(gè)操作執(zhí)行完虑乖,并且不是在主線程中進(jìn)行的
改下代碼
//把之前的方法參數(shù)改為并行屬性
dispatch_queue_t queue1 = dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT);
可以看到結(jié)果是一起執(zhí)行懦趋,執(zhí)行的線程編號(hào)為3和4倆個(gè)線程里,也不是在主線程中進(jìn)行
有可能常見的有一個(gè)這個(gè)疹味, 這是一個(gè)系統(tǒng)全局并行隊(duì)列
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
2.dispatch_group_t
就是一個(gè)隊(duì)列組仅叫,把隊(duì)列給套起來的感覺,線程里面任務(wù)結(jié)束會(huì)發(fā)出一個(gè)消息
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT);
dispatch_group_async(group, queue, ^{
for(int i=0;i<10;i++ ){
NSLog(@" 0當(dāng)前線程 %@",[NSThread currentThread]);
}
});
dispatch_group_async(group, queue, ^{
for(int i=0;i<10;i++ ){
NSLog(@" 1當(dāng)前線程 %@",[NSThread currentThread]);
}
});
dispatch_group_async(group, queue, ^{
for(int i=0;i<10;i++ ){
NSLog(@" 2當(dāng)前線程 %@",[NSThread currentThread]);
}
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"完成");
});
效果:
這樣我們可以在完成異步操作的時(shí)候做一些想做的事情糙捺。
但實(shí)際的操作本身網(wǎng)絡(luò)請(qǐng)求就是異步的诫咱,所以我們要配合下面的方法
//加入組
dispatch_group_enter(group);
//離開組
dispatch_group_leave(group);
//修改后代碼
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT);
dispatch_group_async(group, queue, ^{
dispatch_group_enter(group);
//延遲調(diào)用模擬網(wǎng)絡(luò)請(qǐng)求
dispatch_time_t time=dispatch_time(DISPATCH_TIME_NOW, 5*NSEC_PER_SEC);
dispatch_after(time, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"操作一完成");
dispatch_group_leave(group);
});
});
dispatch_group_async(group, queue, ^{
dispatch_group_enter(group);
//延遲調(diào)用模擬網(wǎng)絡(luò)請(qǐng)求
dispatch_time_t time=dispatch_time(DISPATCH_TIME_NOW, 10*NSEC_PER_SEC);
dispatch_after(time, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"操作二完成");
dispatch_group_leave(group);
});
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"全部完成");
});
可以看出leave和enter得對(duì)應(yīng)上,如果只enter不leave 最后的消息一直不會(huì)走
上面這個(gè)操作可以很好處理一個(gè)界面多個(gè)網(wǎng)絡(luò)請(qǐng)求的問題洪灯,當(dāng)所有的網(wǎng)絡(luò)請(qǐng)求都結(jié)束時(shí)會(huì)得到通知并進(jìn)行操作就可以了