GCD學習筆記
1.dispatch_sync—同步操作
eg: dispatch_queue_t concurrentQueue =dispatch_queue_create("my.concurrent.queue”,DISPATCH_QUEUE_CONCURRENT);
NSLog(@"1");
dispatch_sync(concurrentQueue, ^(){
NSLog(@"2");
[NSThread sleepForTimeInterval:10];
NSLog(@"3");
});
NSLog(@"4”);
輸出信息:12(10s后)34
sync包裹的代碼塊阻塞住當前線程執行代碼,包裹的代碼塊本身依然是順序執行的
dispatch_async—異步操作
eg:dispatch_queue_t concurrentQueue = dispatch_queue_create("my.concurrent.queue", DISPATCH_QUEUE_CONCURRENT);
NSLog(@"1");
dispatch_async(concurrentQueue, ^(){
NSLog(@"2");
[NSThread sleepForTimeInterval:5];
NSLog(@"3");
});
NSLog(@"4”);
輸出 1 4 2 (5s后)3
async不會阻塞當前線程的代碼執行,包裹的代碼塊的本身依然是順序執行的
注意:不能理解為同步是在主線程隊列去執行的,而異步是開一個新的線程隊列去執行代碼!!同步方法調用就是在占用當前線程(可以是主線程也可以是子線程)資源去執行代碼,執行完同步方法才可以執行后面代碼;異步方法就是在當前線程(可以是主線程也可以是子線程)基礎上開辟新的執行分支,讓異步方法之后的代碼不被異步方法代碼阻塞掉。
2.GCD處理費時操作的方式
常見問題分析思路:主觀感覺就是與UI處理相關的操作,比如說點擊滑動如果出現卡頓,可能是主線程執行耗時操作導致。
dispatch_async(dispatch_get_global_queue(0, 0), ^{
//處理耗時操作的代碼塊...
//通知主線程刷新
dispatch_async(dispatch_get_main_queue(), ^{
//回調或者說是通知主線程刷新,
});
});
3.隊列的概念,GCD除了線程同步異步還有隊列的概念
同步異步是線程概念,串行并行是隊列概念。
使用GCD的時候,我們會把需要處理的任務放到Block里面,然后講任務追加到相應的隊列里面,這個隊列,叫Dispatch Queue。然而,存在于兩種Dispatch Queue,一種等待上一個任務執行完畢再執行下一個任務的是串行隊列(如果上面任務沒有執行完畢,下面的任務就不能執行,造成死鎖的現象),一種是不需要等待上一個任務執行完畢,就能執行下一個的并行隊列。GCD為我們提供兩個隊列,dispatch_get_global_queue—全局并行隊列
dispatch_get_main_queue—串行隊列,當然,可以自己定義串行并行隊列
dispatch_queue_t concurrentQueue =dispatch_queue_create("my.concurrent.queue”,DISPATCH_QUEUE_SERIAL);—串行隊列
dispatch_queue_t concurrentQueue =dispatch_queue_create("my.concurrent.queue”,DISPATCH_QUEUE_CONCURRENT);—并行隊列
這兩種隊列和全局并行對列以及主線程串行隊列的區別在哪呢。舉例說明。
1.定義同步異步兩種方法,循環打印3次當前線程
2.創建四種隊列,在主線程中分別調用同步異步方法,查看打印結果。
此時的結論是(此時):
1.主線程中調用同步方法,不開辟新線程。如果調用同步主線程,則會形成死鎖(第一種情況)。
2.主線程中調用異步方法,除調用異步主線程外,都開辟新線程。
加工一下同步異步方法,讓該同步異步方法在非主線程隊列中執行。
結果是
此時結論是(此時):
1.子線程中調用同步方法,不開辟新線程。如果調用同步當前線程隊列,則會形成死鎖(第一種情況)。
2.子線程中調用異步方法,除調用異步當前隊列外,都開辟新線程。
最終結論是:
1.在當前線程下(主線程或子線程),sync同步當前線程所在隊列,如果是該隊列是串行隊列,一定會死鎖,如果是并行隊列,則不開辟新線程;async異步當前線程所在隊列,如果是該隊列是串行隊列,不開辟新線程,如果是并行隊列,則開辟新線程。
2.可以理解為全局并行隊列是自定義并行隊列的實例,主線程隊列是自定義串行隊列的實例,之所以在例1中展示不同是因為當前運行程序的線程就是主線程隊列而已。
3.串行和并行的區別在于開辟新線程時,如果是多個任務,那么并行開辟多個線程,串行只開辟一個線程。
那么,看幾個死鎖的分析。
https://mp.weixin.qq.com/s?__biz=MzA3NzM0NzkxMQ==&mid=216361271&idx=1&sn=50525882289b8841956c79cdb63d30f8&scene=0&key=e57780a9dd53e6fc909f1650042874bba95d3134de321ab8e9761b87db930eadeb15d4440d96a767ce710b2f898798b66d1f9d125f898ffc80b9e7bdc128472fdff783513f01adb3d8a4dd902f2c77bb&ascene=0&uin=NTA4MDg1MjU=&devicetype=iMac+MacBookPro12,1+OSX+OSX+10.12.5+build(16F73)&version=12020710&nettype=WIFI&fontScale=100&pass_ticket=+dHDHWeJCQmC9vm3hv/Rf1qqR77mwMuAMxkXQqJK6mE=
NSOperation學習筆記
NSOperation是基于GCD的延伸。
NSOperation做GCD的事情:
主線程隊列 NSOperationQueue * queue = [NSOperationQueue mainQueue]
自定義并行隊列 NSOperationQueue * queue = [[NSOperationQueue alloc]init];
自定義串行隊列 NSOperationQueue * queue = [[NSOperationQueue alloc]init];queue.maxConcurrentOperationCount=1;
默認添加到隊列的操作都會開辟新線程。
創建NSOperation的方法可以繼承NSOperation類,重新main方法,也可以使用NSBlockOperation,NSInvocationOperation。
NSOperation做GCD以外的事情:
1.給NSOperation添加依賴,讓任務可以按照自己想要的優先級順序執行。
2.設置NSOperationQueue最大并發數。
3.控制NSOperation的狀態(暫停,恢復,取消)