GCD和NSOperation學習筆記

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的狀態(暫停,恢復,取消)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容