使用sync函數往當前串行隊列中添加任務,會卡住當前的串行隊列,一定會產生死鎖。面試
同步和異步的區別在於能不能開啓新的線程。bash
同步(dispatch_sync):在當前線程中執行任務,不具有開啓新線程的能力。網絡
異步(dispatch_async):在新的線程中執行任務,具有開啓新線程的能力。併發
併發和串行的區別在於任務的執行方式。異步
併發:多個任務同時執行。async
串行:一個任務執行完畢後,再執行下一個任務。函數
1.同步函數:oop
無論是併發隊列,仍是串行隊列,仍是主線程,都不會開闢新線程,而且是串行執行。post
2.異步函數:學習
串行隊列:開闢新線程,串行執行。
併發隊列:開闢新線程,併發執行。
主線程:不開闢新線程,串行執行。
1.新人在開發中,會遇到在子線程中使用定時器沒效果,或者子線程任務結束後,再次調用子線程會發現沒反應,這都是線程週期已死的表現。
2.子線程執行完代碼後,生命週期就結束了,即便用強指針指着,也無法後續在調用這個子線程作事了,可是用RunLoop能夠保住子線程的生命週期。
3.強指針是保證這個線程對象在內存中不被銷燬。
4.RunLoop是保證這個線程的生命週期一直存在。
// 在子線程中添加以下代碼便可
// 添加source,使RunLoop不秒退 [[NSRunLoop currentRunLoop] addPort:[[NSPort alloc] init] forMode:NSDefaultRunLoopMode]; // 啓動RunLoop [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; 複製代碼
主線程隊列:
dispatch_queue_t main_queue = dispatch_get_main_queue();
併發隊列:
全局併發隊列
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
局部併發隊列
dispatch_queue_t queue = dispatch_queue_create("myqueu", DISPATCH_QUEUE_CONCURRENT); 串行隊列: dispatch_queue_t queue = dispatch_queue_create("myqueu", DISPATCH_QUEUE_SERIAL); 同步函數: dispatch_sync(queue, ^{ NSLog(@"執行任務"); }); 異步函數: dispatch_async(queue, ^{ NSLog(@"執行任務"); }); 主線程: dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"執行任務"); }); 只執行一次: static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ NSLog(@"執行任務"); }); 延時執行: dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ NSLog(@"執行任務"); }); 異步併發處理耗時操做 dispatch_async(dispatch_get_global_queue(0, 0), ^{ // 更新到主線程 dispatch_async(dispatch_get_main_queue(), ^{ }); }); 隊列組(將多個任務放到一個組裏執行,當全部的任務執行完畢,能夠發出通知,經常使用於網絡請求合併) 建立一個任務組: dispatch_group_t group = dispatch_group_create(); 建立一個併發隊列 dispatch_queue_t global_queue = dispatch_queue_create("myqueu", DISPATCH_QUEUE_CONCURRENT); 添加異步隊列 dispatch_group_async(group, global_queue, ^{ NSLog(@「執行任務1"); }); dispatch_group_async(group, global_queue, ^{ NSLog(@「執行任務2"); }); dispatch_group_async(group, global_queue, ^{ NSLog(@「執行任務3"); }); dispatch_group_notify(group, global_queue, ^{ NSLog(@"全部任務執行完畢」); dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@「主線程更新"); }); }); 複製代碼
1.使用sync函數往不一樣串行隊列中添加任務,不會產生死鎖。
2.使用sync函數往當前或者不一樣併發隊列中添加任務,不會產生死鎖。
3.dispatch_get_global_queue(0, 0)是全局併發隊列。
4.dispatch_queue_t queue = dispatch_queue_create("myqueu", DISPATCH_QUEUE_CONCURRENT)是局部併發隊列。
5.本文若有侵犯隱私或其餘請聯繫我,我將在第一時間整改或刪除。
>做爲一個開發者,有一個學習的氛圍跟一個交流圈子特別重要,這是一個個人iOS交流羣:761407670 進羣密碼‘博客’,無論你是小白仍是大牛歡迎入駐 ,分享BAT,阿里面試題、面試經驗,討論技術, 你們一塊兒交流學習成長!
做者:iOS小蝸牛連接:https://juejin.im/post/6854573221942050824