線程任務(wù)
同步: 在同一個線程中執(zhí)行任務(wù),任務(wù)沒有完成前不返回,會阻塞當(dāng)前線程; dispatch_sync - GCD中在當(dāng)前線程中添加一個同步操作
異步: 另外開辟線程執(zhí)行任務(wù),不影響原來線程中的任務(wù)執(zhí)行;dispatch_async - CGD中另開辟線程中添加一個異步操作
GCD線程隊列
主隊列: 主線程所在的隊列,獲取主隊列 dispatch_get_main_queue()
// 如: 向主隊列中添加異步線程更新UI
dispatch_async(dispatch_get_main_queue(), ^{
// 更新UI操作
[tableView reloadData];
});
全局隊列: 全局并發(fā)隊列,獲取默認(rèn)優(yōu)先級全局并發(fā)隊列 dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)(第一個參數(shù)為隊列的優(yōu)先級,第二個參數(shù)為flags), 多個全局隊列執(zhí)行順序與優(yōu)先級有關(guān)
// 全局并發(fā)隊列有四種優(yōu)先級
/* 隊列優(yōu)先級 高 中(默認(rèn)) 低 后臺
#define DISPATCH_QUEUE_PRIORITY_HIGH 2
#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0
#define DISPATCH_QUEUE_PRIORITY_LOW (-2)
#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN
*/
自定義隊列 : 自定義一個串行隊列 dispatch_queue_create("customQueue",DISPATCH_QUEUE_SERIAL) (第一個參數(shù)為字符常量,為隊列的名稱,第二個參數(shù)為隊列的屬性-隊列的串行與并行屬性)
- 串行隊列:
// 自定義一個串行隊列,添加四個同步任務(wù),任務(wù)會在當(dāng)前隊列所在的線程中順序執(zhí)行. (如果在添加四個異步任務(wù)(即用`dispatch_async`添加任務(wù)),會從新開辟<與當(dāng)前隊列所在線程不同>一個線程,在該線程中順序執(zhí)行這四個任務(wù))
dispatch_queue_t serialQueue = dispatch_queue_create("com.example.SerialQueue", NULL);
NSLog(@"serialQueue %@ ",[NSThread currentThread]);
dispatch_sync(serialQueue, ^{
NSLog(@"dispatch_sync 1 %@",[NSThread currentThread]);
});
dispatch_sync(serialQueue, ^{
sleep(2);
NSLog(@"dispatch_sync 2 %@",[NSThread currentThread]);
});
dispatch_sync(serialQueue, ^{
NSLog(@"dispatch_sync 3 %@",[NSThread currentThread]);
});
dispatch_sync(serialQueue, ^{
NSLog(@"dispatch_sync 4 %@",[NSThread currentThread]);
});
dispatch_sync(serialQueue, ^{
NSLog(@"dispatch_sync 5 %@",[NSThread currentThread]);
});
- 并行隊列
// 創(chuàng)建一個并行隊列,向隊列中添加四個并發(fā)任務(wù),每個任務(wù)都會開辟一個不同的線程,四個任務(wù)同時開始執(zhí)行(如果向并行隊列中添加同步任務(wù),和在串行隊列中添加同步任務(wù)相同效果)
dispatch_queue_t concurrentQueue= dispatch_queue_create("com.example.ConcurrentQueue", DISPATCH_QUEUE_CONCURRENT);
NSLog(@"concurrentQueue %@",[NSThread currentThread]);
dispatch_async(concurrentQueue, ^{
NSLog(@"dispatch_async 1 %@",[NSThread currentThread]);
});
dispatch_async(concurrentQueue, ^{
sleep(3);
NSLog(@"dispatch_async 2 %@",[NSThread currentThread]);
});
dispatch_async(concurrentQueue, ^{
NSLog(@"dispatch_async 3 %@",[NSThread currentThread]);
});
dispatch_async(concurrentQueue, ^{
NSLog(@"dispatch_async 4 %@",[NSThread currentThread]);
});
常用 Dispatch 方法
dispatch_once : 在應(yīng)用程序的整個生命周期里,只執(zhí)行一次
// 單例初始化方法
static SJManager *sjmanager = nil;
- (instancetype)shareManager {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sjmanager = [[SJManager alloc] init];
});
return sjmanager;
}
dispatch_after : 線程任務(wù)延時執(zhí)行
// 在主隊列中添加一個5秒后的打印操作
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"我是5秒后才打印出來的呀");
});
// 其中:dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)) 為線程時間,
dispatch_barrier_async : 界線 異步任務(wù), 一般用于并發(fā)隊列中,在它之前的任務(wù)執(zhí)行完成后執(zhí)行,它執(zhí)行完成后才執(zhí)行它之后的任務(wù)
// 任務(wù)1,2執(zhí)行完之后執(zhí)行任務(wù)3,任務(wù)3執(zhí)行完后執(zhí)行任務(wù)4,5
dispatch_queue_t queue = dispatch_queue_create("barrierQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
sleep(3);
NSLog(@"任務(wù)1");
});
dispatch_async(queue, ^{
NSLog(@"任務(wù)2");
});
dispatch_barrier_async(queue, ^{
NSLog(@"任務(wù)3");
});
dispatch_async(queue, ^{
sleep(3);
NSLog(@"任務(wù)4");
});
dispatch_async(queue, ^{
NSLog(@"任務(wù)5");
});
dispatch_group_create : 創(chuàng)建一個任務(wù)組,即多個線程任務(wù)的組合.
dispatch_group_async : 向任務(wù)組中添加異步任務(wù), 不同任務(wù)所在隊列可以不同.
dispatch_group_async && dispatch_group_notify : 監(jiān)聽隊列任務(wù)全部完成,完成后執(zhí)行 dispatch_group_notify 中任務(wù)
// 合并匯總結(jié)果
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
// 并行執(zhí)行的任務(wù)1
NSLog(@"并行任務(wù)1");
});
dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
// 并行執(zhí)行的任務(wù)2
sleep(3);
NSLog(@"并行任務(wù)2");
});
dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
// 并行執(zhí)行的任務(wù)3
sleep(3);
NSLog(@"并行任務(wù)3");
});
dispatch_group_notify(group, dispatch_get_global_queue(0,0), ^{
// 匯總結(jié)果
NSLog(@"執(zhí)行完成任務(wù)");
});
dispatch_group_async && dispatch_group_wait : 等待隊列任務(wù)完成或超時后繼續(xù)執(zhí)行 通過 dispatch_group_wait 返回值(long)判斷,超時還是完成(返回0)
// 任務(wù)組中四個異步線程, 前三個線程執(zhí)行完成或執(zhí)行10s后執(zhí)行第四個線程
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
// 并行執(zhí)行的任務(wù)1
NSLog(@"并行任務(wù)1");
});
dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
// 執(zhí)行的任務(wù)2
sleep(3);
NSLog(@"并行任務(wù)2");
});
dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
// 執(zhí)行的任務(wù)3
sleep(3);
NSLog(@"并行任務(wù)3");
});
long timeout = dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)));
if (timeout == 0) {
NSLog(@"completed");
}
else {
NSLog(@"timeout");
}
dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
// 執(zhí)行的任務(wù)4
NSLog(@"并行任務(wù)4");
});
dispatch_apply : 同時執(zhí)行多次相同操作
// 無序遍歷一個數(shù)組
NSArray *arr = @[@"1",@"2",@"3",@"4",@"5"];
dispatch_apply(arr.count, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(size_t index) {
NSLog(@"%@",arr[(int)index]);
});