iOS筆記-多線程之GCD

線程任務(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]);
   });
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容