開發(fā)中有時(shí)候可能會(huì)有一些很耗時(shí)的操作,不可能說讓屏幕一直卡著,等操作完成嗡贺,那體驗(yàn)就很尷尬了。所以多線程還是需要來一來的鞍帝。
GCD:
并發(fā)隊(duì)列--同步
NSLog(@"---00000--%@",[NSThread currentThread]);
dispatch_queue_t queue=dispatch_queue_create("aaa", DISPATCH_QUEUE_CONCURRENT);
dispatch_sync(queue, ^{
for (int i=0; i<3; i++) {
NSLog(@"---%d--%@",i,[NSThread currentThread]);
}
});
dispatch_sync(queue, ^{
for (int i=3; i<6; i++) {
NSLog(@"---%d--%@",i,[NSThread currentThread]);
}
});
NSLog(@"---aa--%@",[NSThread currentThread]);
看看結(jié)果
可以看出沒有開啟新線程诫睬,而且是順序執(zhí)行的,需要等待前面的任務(wù)完成后才執(zhí)行后面的任務(wù)帕涌。同步執(zhí)行就是一個(gè)個(gè)來摄凡,所以是同步的話,是什么隊(duì)列蚓曼,執(zhí)行順序沒區(qū)別亲澡。同步和異步?jīng)Q定開不開新線程。
并發(fā)隊(duì)列--異步
NSLog(@"---00000--%@",[NSThread currentThread]);
dispatch_queue_t queue=dispatch_queue_create("bbb", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
for (int i=0; i<3; i++) {
NSLog(@"---%d--%@",i,[NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (int i=3; i<6; i++) {
NSLog(@"---%d--%@",i,[NSThread currentThread]);
}
});
NSLog(@"---bb--%@",[NSThread currentThread]);
編譯結(jié)果如下:
并發(fā)隊(duì)列-異步辟躏,開啟了新的線程谷扣,不按順序執(zhí)行。編譯結(jié)果容易讓人以為是主線程的打印完再打印新開的線程捎琐,但是這里并不是一定先打印完---bb 哦会涎,可以在打印---bb前面先睡一下試試。
串行隊(duì)列--同步
NSLog(@"---00000--%@",[NSThread currentThread]);
dispatch_queue_t queue=dispatch_queue_create("cc", DISPATCH_QUEUE_SERIAL);
dispatch_sync(queue, ^{
for (int i=0; i<3; i++) {
NSLog(@"---%d--%@",i,[NSThread currentThread]);
}
});
dispatch_sync(queue, ^{
for (int i=3; i<6; i++) {
NSLog(@"---%d--%@",i,[NSThread currentThread]);
}
});
NSLog(@"---cc--%@",[NSThread currentThread]);
編譯結(jié)果如下:
這就沒什么好說的了瑞凑,沒開新的線程末秃,順序執(zhí)行。
串行隊(duì)列--異步
NSLog(@"---00000--%@",[NSThread currentThread]);
dispatch_queue_t queue=dispatch_queue_create("dd", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
for (int i=0; i<3; i++) {
NSLog(@"---%d--%@",i,[NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (int i=3; i<6; i++) {
NSLog(@"---%d--%@",i,[NSThread currentThread]);
}
});
NSLog(@"---dd--%@",[NSThread currentThread]);
編譯結(jié)果如下:
可以看出隊(duì)列中的任務(wù)是順序執(zhí)行的籽御。這里也是一樣练慕,并不是一定先打印完---dd 哦,可以在打印---dd前面先睡一下試試技掏。
主隊(duì)列--同步
NSLog(@"---00000--%@",[NSThread currentThread]);//只打印這句
dispatch_queue_t queue=dispatch_get_main_queue();
dispatch_sync(queue, ^{
for (int i=0; i<3; i++) {
NSLog(@"---%d--%@",i,[NSThread currentThread]);
}
});
dispatch_sync(queue, ^{
for (int i=3; i<6; i++) {
NSLog(@"---%d--%@",i,[NSThread currentThread]);
}
});
NSLog(@"---ee--%@",[NSThread currentThread]);
編譯結(jié)果如下:
這種情況就死鎖了铃将,主線程在等同步任務(wù)執(zhí)行完,而同步任務(wù)也在等主線程把這個(gè)同步任務(wù)執(zhí)行完哑梳,互相等待劲阎,死鎖了。
主隊(duì)列--異步
NSLog(@"---h00000--%@",[NSThread currentThread]);
dispatch_queue_t queue=dispatch_get_main_queue();
dispatch_async(queue, ^{
for (int i=0; i<3; i++) {
NSLog(@"---h%d--%@",i,[NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (int i=3; i<6; i++) {
NSLog(@"---h%d--%@",i,[NSThread currentThread]);
}
});
NSLog(@"---h ee--%@",[NSThread currentThread]);
編譯結(jié)果如下:
將任務(wù)放到主隊(duì)列鸠真,不會(huì)馬上執(zhí)行悯仙,要等到所有除了我們自己添加到主隊(duì)列的任務(wù)的任務(wù)都執(zhí)行完畢才會(huì)執(zhí)行我們自己添加到主隊(duì)列的任務(wù)。所以---h00000后面一定先打印---h ee 再打印剩下的吠卷。
- 全局隊(duì)列
這玩意兒跟并發(fā)隊(duì)列一樣就不說了锡垄。
隊(duì)列組
NSLog(@"---hello");
dispatch_group_t group=dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
for (int i=0; i<3; i++) {
NSLog(@"---%d--%@",i,[NSThread currentThread]);
}
});
dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
for (int i=3; i<6; i++) {
NSLog(@"---%d--%@",i,[NSThread currentThread]);
}
});
dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{
for (int i=6; i<9; i++) {
NSLog(@"---%d--%@",i,[NSThread currentThread]);
}
});
NSLog(@"---end");
編譯結(jié)果如下:
有時(shí)候是這種需求,分別執(zhí)行兩個(gè)耗時(shí)操作祭隔,等這兩個(gè)耗時(shí)操作執(zhí)行完货岭,再做別的操作。如上圖疾渴,前兩個(gè)異步執(zhí)行完千贯,再執(zhí)行dispatch_group_notify里的任務(wù)。
dispatch_group_enter,dispatch_group_leave
這個(gè)時(shí)候有這樣的情況程奠,如果組隊(duì)列異步操作里也是異步那么dispatch_group_notify會(huì)直接響應(yīng)(可以模仿耗時(shí)操作試試)丈牢。這個(gè)時(shí)候就要用dispatch_group_enter,dispatch_group_leave了。
NSLog(@"---hello");
dispatch_group_t group=dispatch_group_create();
//dispatch_group_enter(group);
dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[NSThread sleepForTimeInterval:5.0];
NSLog(@"---h1--%@",[NSThread currentThread]);
//dispatch_group_leave(group);
});
});
//dispatch_group_enter(group);
dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[NSThread sleepForTimeInterval:8.0];
NSLog(@"---h2--%@",[NSThread currentThread]);
//dispatch_group_leave(group);
});
});
dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{
NSLog(@"---h3--%@",[NSThread currentThread]);
});
NSLog(@"---h end");
編譯結(jié)果如下:
這樣就能保證先執(zhí)行前面的異步任務(wù)之后再執(zhí)行dispatch_group_notify里的任務(wù)瞄沙;
dispatch_group_wait --(在group上任務(wù)完成前己沛,dispatch_group_wait會(huì)阻塞當(dāng)前線程(所以不能放在主線程調(diào)用)一直等待;當(dāng)group上任務(wù)完成距境,或者等待時(shí)間超過設(shè)置的超時(shí)時(shí)間會(huì)結(jié)束等待申尼;)
NSLog(@"---hello");
dispatch_group_t group=dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
NSLog(@"---h1--%@",[NSThread currentThread]);
});
dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
[NSThread sleepForTimeInterval:8.0];
NSLog(@"---h2--%@",[NSThread currentThread]);
});
dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{
NSLog(@"---h3--%@",[NSThread currentThread]);
});
dispatch_async(dispatch_get_global_queue(0, 0), ^{
dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5*NSEC_PER_SEC)));
NSLog(@"---h4---%@",[NSThread currentThread]);
});
NSLog(@"---h end");
編譯結(jié)果如下:
dispatch_barrier_async(柵欄方法(將兩組異步分割開來))
NSLog(@"---00000--%@",[NSThread currentThread]);
dispatch_queue_t queue=dispatch_queue_create("hehe", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
for (int i=0; i<3; i++) {
NSLog(@"---%d--%@",i,[NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (int i=3; i<6; i++) {
NSLog(@"---%d--%@",i,[NSThread currentThread]);
}
});
dispatch_barrier_async(queue, ^{
for (int i=6; i<9; i++) {
NSLog(@"---%d--%@",i,[NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (int i=9; i<12; i++) {
NSLog(@"---%d--%@",i,[NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (int i=12; i<15; i++) {
NSLog(@"---%d--%@",i,[NSThread currentThread]);
}
});
NSLog(@"---ff--%@",[NSThread currentThread]);
編譯結(jié)果如下:
可以看出前面兩個(gè)異步先執(zhí)行完,再執(zhí)行的后面兩個(gè)異步垫桂。
延時(shí)
NSLog(@"---hello");
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0*NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//2s后異步執(zhí)行
NSLog(@"---h---come !");
});
NSLog(@"---h end");
編譯結(jié)果如下:
- dispatch_once單例 就不寫了师幕。