GCD 總結(jié)(一)

1.延時(shí)操作

GCD ? ? ? dispatch_after() ?優(yōu)點(diǎn):寫起來(lái)方便,直觀 ? ? ?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 缺點(diǎn):1. 精確度不高 ?2.沒(méi)有取消操作

例如:記住了:最好在主隊(duì)列中使用 dispatch_after 的好選擇;Xcode 提供了一個(gè)不錯(cuò)的自動(dòng)完成模版。

dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));// 1

dispatch_after(popTime,?dispatch_get_main_queue(),?^(void){//?2

//操作任務(wù)

}

});

NSThread? performSelector:@selector(delayMethod) withObject:nil afterDelay:單線程 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 優(yōu)點(diǎn):精確度高 ? 可以取消延遲執(zhí)行操作


2. 定時(shí)器

GCD ? ? ?優(yōu)點(diǎn):

NSTimer ?優(yōu)點(diǎn):相對(duì)精確度高 ? ? 缺點(diǎn):UITableview 滾動(dòng)時(shí),timer停止

3. 信號(hào)源:線程1,線程2,線程3,他們都是異步的,正常情況是沒(méi)有順序的,加上信號(hào)員,一個(gè)結(jié)束完了,再執(zhí)行另外一個(gè),這樣就是有序了

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{? //線程一 });

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{? //線程二});

4.單例

5.隊(duì)列類型:

第一:主線程隊(duì)列

第二:全局線程隊(duì)列dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)

第三:自定義線程隊(duì)列,自定義串行隊(duì)列(當(dāng)你想串行執(zhí)行后臺(tái)任務(wù)并追蹤它時(shí)就是一個(gè)好選擇)dispatch_queue_t ??queue = dispatch_queue_create("cn.itcast.queue", NULL);

案例問(wèn)題:當(dāng)一個(gè)線程A調(diào)用讀方法 photos 的同時(shí),另一個(gè)線程B調(diào)用寫方法 addPhoto: 在同時(shí)對(duì)一個(gè)NSMutableArray進(jìn)行操作。

Dispatch barriers就是來(lái)解決這個(gè)問(wèn)題的。

GCD (barrier)保證了在某個(gè)時(shí)間點(diǎn)上,在并行的多線程中,只有一個(gè)線程對(duì)某個(gè)資源進(jìn)行訪問(wèn),其他的線程先暫停執(zhí)行

怎么用這個(gè)barrier,最好只用在自定義隊(duì)列中的并發(fā)隊(duì)列,原因:barrier肯定是用在異步線程中,首先主線程用不上,然后就是全局并發(fā)隊(duì)列,要小心;這可能不是最好的主意,因?yàn)槠渌到y(tǒng)可能在使用隊(duì)列而且你不能壟斷它們只為你自己的目的。最后. 自定義串行隊(duì)列

打開(kāi) PhotoManager.m,添加如下私有屬性到類擴(kuò)展中:

@interfacePhotoManager?()

@property?(nonatomic,strong,readonly)?NSMutableArray?*photosArray;

@property?(nonatomic,?strong)?dispatch_queue_t?concurrentPhotoQueue;///<?Add?this

@end

找到 addPhoto: 并用下面的實(shí)現(xiàn)替換它:

-?(void)addPhoto:(Photo?*)photo{

if(photo)?{//?1

dispatch_barrier_async(self.concurrentPhotoQueue,?^{//?2

[_photosArray?addObject:photo];//?3

dispatch_async(dispatch_get_main_queue(),?^{//?4

[self?postContentAddedNotification];});});}

}

這個(gè)并沒(méi)有結(jié)束哦,這就處理了寫操作,但你還需要實(shí)現(xiàn) photos 讀方法并實(shí)例化 concurrentPhotoQueue 。在寫者打擾的情況下,要確保線程安全,你需要在 concurrentPhotoQueue 隊(duì)列上執(zhí)行讀操作。既然你需要從函數(shù)返回,你就不能異步調(diào)度到隊(duì)列,因?yàn)槟菢釉谧x者函數(shù)返回之前不一定運(yùn)行。

在這種情況下,dispatch_sync 就是一個(gè)絕好的候選。

- (NSArray *)photos

{__block?NSArray?*array;//?1

dispatch_sync(self.concurrentPhotoQueue,?^{//?2

array?=?[NSArray?arrayWithArray:_photosArray];//?3

});returnarray;}

最后,你需要實(shí)例化你的 concurrentPhotoQueue 屬性。修改 sharedManager 以便像下面這樣初始化隊(duì)列:

+?(instancetype)sharedManager

{

staticPhotoManager?*sharedPhotoManager?=?nil;

staticdispatch_once_t?onceToken;

dispatch_once(&onceToken,?^{

sharedPhotoManager?=?[[PhotoManager?alloc]?init];

sharedPhotoManager->_photosArray?=?[NSMutableArray?array];

//?ADD?THIS:

sharedPhotoManager->_concurrentPhotoQueue?=?dispatch_queue_create("com.selander.GooglyPuff.photoQueue",DISPATCH_QUEUE_CONCURRENT);

});

returnsharedPhotoManager;

}



? ?

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

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

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