隊列類型
并發(fā)隊列(Concurrent Dispatch Queue)任務(wù)并發(fā)(同步)執(zhí)行
串行隊列(Serial Dispatch Queue)任務(wù)順序執(zhí)行
全局隊列(Global Queue)并發(fā)隊列
主隊列(Main Queue)串行隊列
/**
* lable : 隊列名稱
* attr : 隊列類型晤揣,并發(fā)(ConCurrent),串行(Serial 或 NULL)
*/
dispatch_queue_t conCurrentQueue = dispatch_queue_create("conCurrent", DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t serialQueue = dispatch_queue_create("serial", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t serialQueue1 = dispatch_queue_create("serial1", NULL);
/**
* 全局并發(fā)隊列
* identifier : 優(yōu)先級
* flags : 設(shè)置為0即可
*/
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
/**
* 主隊列,串行隊列
*/
dispatch_queue_t mainQueue = dispatch_get_main_queue();
執(zhí)行方式
同步執(zhí)行-在當(dāng)前線程執(zhí)行
異步執(zhí)行-在新線程執(zhí)行
queue:隊列
block:任務(wù)翎朱,需要進(jìn)行的操作
//同步任務(wù)
dispatch_sync(<#dispatch_queue_t queue#>, <#^(void)block#>)
//異步任務(wù)
dispatch_async(<#dispatch_queue_t queue#>, <#^(void)block#>)
代碼示例
- 異步任務(wù) + 串行隊列
開啟新線程,串行執(zhí)行任務(wù)贸辈。
dispatch_queue_t serialCurrentQueue = dispatch_queue_create("myQueue", NULL);
dispatch_async(serialCurrentQueue, ^{
NSLog(@"串行隊列-異步任務(wù)1-%@", [NSThread currentThread]);
});
dispatch_async(serialCurrentQueue, ^{
NSLog(@"串行隊列-異步任務(wù)2-%@", [NSThread currentThread]);
});
dispatch_async(serialCurrentQueue, ^{
NSLog(@"串行隊列-異步任務(wù)3-%@", [NSThread currentThread]);
});
dispatch_async(serialCurrentQueue, ^{
NSLog(@"串行隊列-異步任務(wù)4-%@", [NSThread currentThread]);
});
NSLog(@"執(zhí)行完成");
/*
執(zhí)行完成
串行隊列-異步任務(wù)1-<NSThread: 0x7f9f32e1de80>{number = 2, name = (null)}
串行隊列-異步任務(wù)2-<NSThread: 0x7f9f32e1de80>{number = 2, name = (null)}
串行隊列-異步任務(wù)3-<NSThread: 0x7f9f32e1de80>{number = 2, name = (null)}
串行隊列-異步任務(wù)4-<NSThread: 0x7f9f32e1de80>{number = 2, name = (null)}
*/
- 異步任務(wù) + 并行隊列
開啟新線程王滤,同步執(zhí)行任務(wù)。
dispatch_queue_t conCurrentQueue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(conCurrentQueue, ^{
NSLog(@"并發(fā)隊列-異步任務(wù)1-%@", [NSThread currentThread]);
});
dispatch_async(conCurrentQueue, ^{
NSLog(@"并發(fā)隊列-異步任務(wù)2-%@", [NSThread currentThread]);
});
dispatch_async(conCurrentQueue, ^{
NSLog(@"并發(fā)隊列-異步任務(wù)3-%@", [NSThread currentThread]);
});
dispatch_async(conCurrentQueue, ^{
NSLog(@"并發(fā)隊列-異步任務(wù)4-%@", [NSThread currentThread]);
});
NSLog(@"執(zhí)行完成");
/*
執(zhí)行完成
并發(fā)隊列-異步任務(wù)1-<NSThread: 0x7fb751e1a6a0>{number = 5, name = (null)}
并發(fā)隊列-異步任務(wù)3-<NSThread: 0x7fb751d08830>{number = 6, name = (null)}
并發(fā)隊列-異步任務(wù)2-<NSThread: 0x7fb751d0ee50>{number = 2, name = (null)}
并發(fā)隊列-異步任務(wù)4-<NSThread: 0x7fb751d0f340>{number = 4, name = (null)}
或
并發(fā)隊列-異步任務(wù)2-<NSThread: 0x7fb751d01d20>{number = 10, name = (null)}
執(zhí)行完成
并發(fā)隊列-異步任務(wù)1-<NSThread: 0x7fb751d06210>{number = 9, name = (null)}
并發(fā)隊列-異步任務(wù)3-<NSThread: 0x7fb751d0f400>{number = 11, name = (null)}
并發(fā)隊列-異步任務(wù)4-<NSThread: 0x7fb751d08830>{number = 8, name = (null)}
*/
- 異步任務(wù) + 主線程
不開啟新線程鸟废,在主線程串行執(zhí)行任務(wù)。
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_async(mainQueue, ^{
NSLog(@"主隊列-異步任務(wù)1-%@", [NSThread currentThread]);
});
dispatch_async(mainQueue, ^{
NSLog(@"主隊列-異步任務(wù)2-%@", [NSThread currentThread]);
});
dispatch_async(mainQueue, ^{
NSLog(@"主隊列-異步任務(wù)3-%@", [NSThread currentThread]);
});
dispatch_async(mainQueue, ^{
NSLog(@"主隊列-異步任務(wù)4-%@", [NSThread currentThread]);
});
NSLog(@"執(zhí)行完成");
/*
執(zhí)行完成
主隊列-異步任務(wù)1-<NSThread: 0x7f8ccb601ec0>{number = 1, name = main}
主隊列-異步任務(wù)2-<NSThread: 0x7f8ccb601ec0>{number = 1, name = main}
主隊列-異步任務(wù)3-<NSThread: 0x7f8ccb601ec0>{number = 1, name = main}
主隊列-異步任務(wù)4-<NSThread: 0x7f8ccb601ec0>{number = 1, name = main}
*/
- 同步任務(wù) + 串行隊列
不開啟新線程姑荷,串行執(zhí)行任務(wù)盒延。
dispatch_queue_t serialCurrentQueue = dispatch_queue_create("myQueue", NULL);
dispatch_sync(serialCurrentQueue, ^{
NSLog(@"串行隊列-同步任務(wù)1-%@", [NSThread currentThread]);
});
dispatch_sync(serialCurrentQueue, ^{
NSLog(@"串行隊列-同步任務(wù)2-%@", [NSThread currentThread]);
});
dispatch_sync(serialCurrentQueue, ^{
NSLog(@"串行隊列-同步任務(wù)3-%@", [NSThread currentThread]);
});
dispatch_sync(serialCurrentQueue, ^{
NSLog(@"串行隊列-同步任務(wù)4-%@", [NSThread currentThread]);
});
NSLog(@"執(zhí)行完成");
/*
串行隊列-同步任務(wù)1-<NSThread: 0x7f99c8600190>{number = 1, name = main}
串行隊列-同步任務(wù)2-<NSThread: 0x7f99c8600190>{number = 1, name = main}
串行隊列-同步任務(wù)3-<NSThread: 0x7f99c8600190>{number = 1, name = main}
串行隊列-同步任務(wù)4-<NSThread: 0x7f99c8600190>{number = 1, name = main}
執(zhí)行完成
*/
- 同步任務(wù) + 并行隊列
不開啟新線程,串行執(zhí)行任務(wù)鼠冕。
dispatch_queue_t conCurrentQueue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_sync(conCurrentQueue, ^{
NSLog(@"并發(fā)隊列-同步任務(wù)1-%@", [NSThread currentThread]);
});
dispatch_sync(conCurrentQueue, ^{
NSLog(@"并發(fā)隊列-同步任務(wù)2-%@", [NSThread currentThread]);
});
dispatch_sync(conCurrentQueue, ^{
NSLog(@"并發(fā)隊列-同步任務(wù)3-%@", [NSThread currentThread]);
});
dispatch_sync(conCurrentQueue, ^{
NSLog(@"并發(fā)隊列-同步任務(wù)4-%@", [NSThread currentThread]);
});
NSLog(@"執(zhí)行完成");
/*
并發(fā)隊列-同步任務(wù)1-<NSThread: 0x7fc1d2d08820>{number = 1, name = main}
并發(fā)隊列-同步任務(wù)2-<NSThread: 0x7fc1d2d08820>{number = 1, name = main}
并發(fā)隊列-同步任務(wù)3-<NSThread: 0x7fc1d2d08820>{number = 1, name = main}
并發(fā)隊列-同步任務(wù)4-<NSThread: 0x7fc1d2d08820>{number = 1, name = main}
執(zhí)行完成
*/
- 同步任務(wù) + 主隊列
阻塞主線程
dispatch_queue_t mainQueue = dispatch_get_main_queue();
NSLog(@"任務(wù)開始");
dispatch_sync(mainQueue, ^{
NSLog(@"主隊列-同步任務(wù)1-%@", [NSThread currentThread]);
});
NSLog(@"執(zhí)行完成");
/*主隊列等待同步任務(wù)完成添寺,同步任務(wù)等待主隊列執(zhí)行完,相互等待懈费,誰都完成不了计露。
任務(wù)開始
*/
表格總結(jié)
全局、并發(fā)隊列 | 自建串行隊列 | 主隊列 | |
---|---|---|---|
同步任務(wù) | 不開啟新線程;串行執(zhí)行任務(wù) | 不開啟新線程憎乙;串行執(zhí)行任務(wù) | 造成死鎖 |
異步任務(wù) | 開啟新線程票罐;并發(fā)執(zhí)行任務(wù) | 開啟新線程;串行執(zhí)行任務(wù) | 不開啟新線程泞边;串行執(zhí)行任務(wù) |
GCD調(diào)度組(線程組)
異步執(zhí)行多個任務(wù)该押,當(dāng)所有任務(wù)執(zhí)行完成后,再執(zhí)行某個任務(wù)阵谚。
GCD線程間通訊
主隊列=主線程=UI線程蚕礼,所有的界面刷新都需要在主線程進(jìn)行烟具,子線程完成操作后,拿到主線程奠蹬,在主線程進(jìn)行刷新界面朝聋。
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_async(queue, ^{
//執(zhí)行耗時任務(wù)
//...
dispatch_async(dispatch_get_main_queue(), ^{
//在主線程進(jìn)行界面刷新
//...
});
});
GCD延時函數(shù)
//第一種
[self performSelector:@selector(showMessage) withObject:nil afterDelay:2.0f];
//第二種
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//2秒后執(zhí)行的操作
//...
});
GCD執(zhí)行一次函數(shù)
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//只需要執(zhí)行一次的代碼
//...
});
GCD柵欄函數(shù)
在并發(fā)隊列插入柵欄函數(shù),會先執(zhí)行柵欄函數(shù)之前的操作罩润,再執(zhí)行柵欄函數(shù)玖翅,最后執(zhí)行柵欄函數(shù)后面的操作,起到柵欄的作用割以。
dispatch_queue_t queue = dispatch_queue_create("name", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"耗時操作1-%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"耗時操作2-%@", [NSThread currentThread]);
});
dispatch_barrier_async(queue, ^{
NSLog(@"柵欄函數(shù)-%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"耗時操作3-%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"耗時操作4-%@", [NSThread currentThread]);
});
NSLog(@"執(zhí)行完成");
/*
執(zhí)行完成
耗時操作2-<NSThread: 0x7ff4b2dad620>{number = 2, name = (null)}
耗時操作1-<NSThread: 0x7ff4b2c04bc0>{number = 3, name = (null)}
柵欄函數(shù)-<NSThread: 0x7ff4b2c04bc0>{number = 3, name = (null)}
耗時操作4-<NSThread: 0x7ff4b2dad620>{number = 2, name = (null)}
耗時操作3-<NSThread: 0x7ff4b2c04bc0>{number = 3, name = (null)}
*/
GCD-dispatch_apply()函數(shù)
提交任務(wù)到隊列中多次執(zhí)行金度,由隊列決定并行還是串行。dispatch_apply為同步任務(wù)严沥,執(zhí)行完dispatch_apply才會執(zhí)行下面的操作猜极。
/* iterations 執(zhí)行的次數(shù)
queue 提交到的隊列
size_t 索引,需要自己指定一個參數(shù)
block 執(zhí)行的任務(wù)
dispatch_apply(size_t iterations, dispatch_queue_t queue, <#^(size_t)block#>)
*/
dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);
dispatch_apply(4, globalQueue, ^(size_t index) {
//執(zhí)行的循環(huán)操作
NSLog(@"次數(shù)%d-%@", index, [NSThread currentThread]);
});
NSLog(@"執(zhí)行完成");
/*
次數(shù)0-<NSThread: 0x7f9da35020d0>{number = 1, name = main}
次數(shù)1-<NSThread: 0x7f9da340be60>{number = 2, name = (null)}
次數(shù)3-<NSThread: 0x7f9da3740740>{number = 4, name = (null)}
次數(shù)2-<NSThread: 0x7f9da3608440>{number = 3, name = (null)}
執(zhí)行完成
*/