久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Grand Central Dispatch (GCD) 用法詳細介紹

 最初九月雪 2015-05-29
1. Dispatch Queue
執(zhí)行處理有兩種Dispatch Queue,。
一種是等待現(xiàn)在執(zhí)行中的處理的Serial Dispatch Queue,。(順序執(zhí)行)
另一種是不等待現(xiàn)在執(zhí)行中處理的Concurrent Dispatch Queue,。(并行執(zhí)行)

Concurrent Dispatch Queue執(zhí)行:
線程0 線程1 線程2 線程3
blk0 blk1 blk2 blk3
blk5 blk6 blk4  
blk7      


2. dispatch_queue_create
通過 dispatch_queue_create 函數(shù)可以生成 Dispathch Queue,。

  1. // 第一個參數(shù)為queue署名,。第二個參數(shù)為創(chuàng)建的queue類型。null默認為Serial dispatch queue  
  2. dispatch_queue_t myDispatchQueue = dispatch_queue_create(“com.example.queue”, NULL);  
  3.   
  4. // dispatch_queue_t myDispatchQueue = dispatch_queue_create(“com.example.queue”, DIDPATCH_QUEUE_CONCURRENT);  
  5.   
  6. dispatch_async(myDispatchQueue, ^{ NSLog(@“ block on queue “); });  
  7.   
  8. // 結(jié)束后需要release  
  9. dispatch_release(myDispatchQueue);  
  10.   
  11. // 相應(yīng)的有retain函數(shù)  
  12. // dispatch_retain(myDispatchQueue);  

雖然一執(zhí)行完 dispatch_async 后里面釋放queue,,但是由于Block持有該Dispatch Queue,,所以此處release后 queue 不會被廢棄。


3. Main Dispatch Queue 和 Global Dispatch Queue
以上兩種為系統(tǒng)標準提供的Dispatch Queue,;

名稱 Dispatch Queue種類 說明
Main Dispatch Queue Serial Dispatch Queue 主線程執(zhí)行
DISPATCH_QUEUE_PRIORITY_HIGH Concurrent Dispatch Queue 高優(yōu)先級
DISPATCH_QUEUE_PRIORITY_DEFAULT Concurrent Dispatch Queue 默認優(yōu)先級
DISPATCH_QUEUE_PRIORITY_LOW Concurrent Dispatch Queue 低優(yōu)先級
DISPATCH_QUEUE_PRIORITY_BACKGROUND Concurrent Dispatch Queue 后臺執(zhí)行

  1. // 獲取主線程  
  2. dispatch_queue_t mainDispatchQueue = dispatch_get_main_queue();  
  3.   
  4. //   
  5. dispatch_queue_t globalDispatchQueueHigh = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);  
  6.   
  7. //   
  8. dispatch_queue_t globalDispatchQueueDefault = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);  
  9.   
  10. //   
  11. dispatch_queue_t globalDispatchQueueLow = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);  
  12.   
  13. //   
  14. dispatch_queue_t globalDispatchQueueBackground = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);  

注:dispatch_retain() 和 dispatch_release() 對于這兩種queue不會引起任何變化,。


4. dispatch_set_target_queue
dispatch_queue_create() 函數(shù)生成的無論是Serial 還是 Concurrent ,都是默認優(yōu)先級,。
使用 dispatch_set_target_queue 可以變更優(yōu)先級,。
例如:
  1. dispatch_queue_t myDispatchQueue = dispatch_queue_create(“com.example.queue”, NULL);  
  2. dispatch_queue_t globalDispatchQueueBackground = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);  
  3. dispatch_set_target_queue(myDispatchQueue, globalDispatchQueueBackground);  

以上代碼將 myDispatchQueue 的優(yōu)先級變更為 后臺優(yōu)先級。


5. dispatch_after
想要在指定時間后執(zhí)行處理,,可使用 dispatch_after,。
例如:3秒后將指定的Block 追加奧 Main Dispatch Queue 中。

  1. dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 33ull * NSEC_PER_SEC);  
  2. dispatch_after(time, dispatch_get_main_queue(), ^{ NSLog(@“waited at least three seconds.”); });  

注: dispatch_after 函數(shù)并不是在指定時間后執(zhí)行處理,,而是在指定時間后追加處理到Dispatch Queue,。例如Main Dispatch Queue在主線程的RunLoop中執(zhí)行。所以在比如每隔1/60秒執(zhí)行的RunLoop,,Block最快在3秒后執(zhí)行,,最慢在 3+1/60秒后執(zhí)行。


6. Dispatch Group
如果想要在追加到多個Dispatch Queue中的多個處理全部結(jié)束后執(zhí)行結(jié)束處理,,,,可使用Dispatch Group。
例如:

  1. dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);  
  2. dispatch_group_t group = dispatch_group_create();  
  3.   
  4. dispatch_group_async(group, queue, ^{NSLog(@“bll0”);});  
  5. dispatch_group_async(group, queue, ^{NSLog(@“bll1”);});  
  6. dispatch_group_async(group, queue, ^{NSLog(@“bll2”);});  
  7.   
  8. dispatch_group_notify(group, dispatch_get_main_queue(), ^{ NSLog(@“done”); });  
  9. dispatch_release(group);  


其中可以使用 dispatch_group_wait函數(shù)僅等待全部處理執(zhí)行結(jié)束:
  1. dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);  
  2. dispatch_group_t group = dispatch_group_create();  
  3.   
  4. dispatch_group_async(group, queue, ^{NSLog(@“bll0”);});  
  5. dispatch_group_async(group, queue, ^{NSLog(@“bll1”);});  
  6. dispatch_group_async(group, queue, ^{NSLog(@“bll2”);});  
  7.   
  8. dispatch_group_wait(group, DISPATCH_TIME_FOREVER);  
  9. dispatch_release(group);   

注:dispatch_group_wait 的返回值為0,,標識全部處理執(zhí)行結(jié)束,;
返回值不為0,表示經(jīng)過了指定時間,,屬于Dispatch Group 的某一個處理還在執(zhí)行中;
由于 DISPATCH_TIME_FOREVER 標識永久等待,,故而返回值恒為0,;

dispatch_group_wait 可能會造成當前線程停止,,直至所有處理執(zhí)行結(jié)束。

7. dispatch_barrier_async
在多個并行處理之間插入指定處理后再繼續(xù)多個并行處理,。
例如:
  1. dispatch_queue_t queue = dispatch_queue_create(“com.example.queue”, DISPATCH_QUEUE_CONCURRENT);  
  2.   
  3. dispatch_async(queue, blk0_for_reading);   
  4. dispatch_async(queue, blk1_for_reading);   
  5. dispatch_async(queue, blk2_for_reading);   
  6. dispatch_async(queue, blk3_for_reading);   
  7. dispatch_barrier_async(queue, blk_for_writing);  
  8. dispatch_async(queue, blk4_for_reading);   
  9. dispatch_async(queue, blk5_for_reading);   
  10. dispatch_async(queue, blk6_for_reading);   
  11. dispatch_async(queue, blk7_for_reading);   
  12. dispatch_async(queue, blk8_for_reading);   
  13.   
  14. dispatch_release(queue);  

使用 Concurrent Dispatch Queue 和 dispatch_barrier_async 可實現(xiàn)高效率的數(shù)據(jù)庫訪問和文件訪問,。


8. dispatch_apply
該函數(shù)按指定的次數(shù)將指定的Block追加到指定的Dispatch Queue中,并等待全部處理執(zhí)行結(jié)束,。
例如:
  1. dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);  
  2. dispatch_apply(5, queue, ^(size_t index){ NSLog(@“%zu”, index); });  
  3. NSLog(@“done”);  

  1. // 運行結(jié)果  
  2. 4  
  3. 1  
  4. 0  
  5. 3  
  6. 2  
  7. done  


9. dispatch_suspend / dispatch_resume
當追加大量處理到Dispatch Queue時,,在追加處理的過程中,希望不執(zhí)行一追加的處理,,例如驗算結(jié)果被Block截獲時,,一些處理會對這個演算結(jié)果造成影響。
可使用以上兩個函數(shù)掛起和恢復queue,。


10. Dispatch Semaphore
該函數(shù)是比 dispatch_barrier_async() 更細粒度的排他控制,。
先看一下例子:

  1. dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);  
  2. NSMutableArray *array = [[NSMutableArray alloc] init];  
  3. for(int i = 0; i< 100000; ++i)  
  4. {  
  5.      dispatch_async(queue, ^{ [array addObject:[NSNumber numberWithInt:i]]; });  
  6. }  


以上代碼執(zhí)行后由內(nèi)存錯誤導致應(yīng)用異常結(jié)束的概率很高。
Dispatch Semaphore 是持有計數(shù)的信號,。當計數(shù)為0時,,表示等待;計數(shù)為1或者大于1時,,減去1而不等待,;

  1. // 生成函數(shù),計數(shù)初始值為1  
  2. dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);  
  3.   
  4. // 一直等待,直到Dispatch Semaphore 的計數(shù)值達到大于等于1,;  
  5. long result = dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);  
  6. if (result == 0)  
  7. {  
  8.      // 可執(zhí)行其他需要進行排他控制的處理  
  9. }else{  
  10.      // 在達到指定時間為止待機  
  11. }  

修改后的例子:
  1. dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);  
  2. // 保證可訪問NSMutableArray 的線程同時只能有一個  
  3. dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);  
  4.   
  5. NSMutableArray *array = [[NSMutableArray alloc] init];  
  6. for(int i = 0; i< 100000; ++i)  
  7. {  
  8.      dispatch_async(queue, ^{   
  9.           dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);  
  10.           [array addObject:[NSNumber numberWithInt:i]];   
  11.      });  
  12. }   
  13. dispatch_release(semaphore);  


11. dispatch_once
dispatch_once 函數(shù)保證在應(yīng)用程序執(zhí)行中只執(zhí)行一次指定處理的API,;
例如:
  1. static int initialized = NO;  
  2. if (initialized == NO)  
  3. {  
  4.      //initialized  
  5.      initialized = YES;  
  6. }  


可轉(zhuǎn)變成:
  1. static dispatch_once_t pred;  
  2. dispatch_once(&pred, ^{  
  3.      //initialized  
  4. });  





































    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,,謹防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多