GCD

dispatch_barrier_async ?函數(shù)的作用:如果任務(wù)是通過dispatch_barrier_async函數(shù)追加到concurrent queue中的,執(zhí)行該任務(wù)時(shí),其他的線程不執(zhí)行,直到該任務(wù)完成,才恢復(fù)執(zhí)行剩余的任務(wù).

創(chuàng)建并行隊(duì)列 : dispatch_queue_t concurrentQueue = dispatch_queue_create("my.concurrent.queue", DISPATCH_QUEUE_CONCURRENT);

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

創(chuàng)建串行隊(duì)列 :? dispatch_queue_t queue = dispatch_queue_create("tk.bourne.testQueue", NULL); //DISPATCH_QUEUE_SERIAL

NSOperation 是蘋果公司對(duì) GCD 的封裝,完全面向?qū)ο螅允褂闷饋砀美斫狻?大家可以看到 NSOperation 和 NSOperationQueue 分別對(duì)應(yīng) GCD 的 任務(wù) 和 隊(duì)列 。

*1//1.創(chuàng)建NSInvocationOperation對(duì)象

NSInvocationOperation?*operation?=?[[NSInvocationOperation?alloc]?initWithTarget:self?selector:@selector(run)?object:nil];

//2.開始執(zhí)行

[operation?start];

*2//1.創(chuàng)建NSBlockOperation對(duì)象

NSBlockOperation?*operation?=?[NSBlockOperation?blockOperationWithBlock:^{

NSLog(@"%@",?[NSThread?currentThread]);

}];

//2.開始任務(wù)

[operation?start];

NSBlockOperation 還有一個(gè)方法:addExecutionBlock: ,通過這個(gè)方法可以給 Operation 添加多個(gè)執(zhí)行 Block。這樣 Operation 中的任務(wù) 會(huì)并發(fā)執(zhí)行,它會(huì) 在主線程和其它的多個(gè)線程 執(zhí)行這些任務(wù)

//1.創(chuàng)建一個(gè)其他隊(duì)列

NSOperationQueue?*queue?=?[[NSOperationQueue?alloc]?init];

//2.創(chuàng)建NSBlockOperation對(duì)象

NSBlockOperation?*operation?=?[NSBlockOperation?blockOperationWithBlock:^{

NSLog(@"%@",?[NSThread?currentThread]);

}];

//3.添加多個(gè)Block

for(NSInteger?i?=?0;?i?<?5;?i++)?{

[operation?addExecutionBlock:^{

NSLog(@"第%ld次:%@",?i,?[NSThread?currentThread]);

}];

}

//4.隊(duì)列添加任務(wù)

[queue?addOperation:operation];

OK, 這時(shí)應(yīng)該發(fā)問了,大家將 NSOperationQueue 與 GCD的隊(duì)列 相比較就會(huì)發(fā)現(xiàn),這里沒有并行隊(duì)列,那如果我想要10個(gè)任務(wù)在其他線程串行的執(zhí)行怎么辦?

這就是蘋果封裝的妙處,你不用管串行、并行、同步、異步這些名詞。NSOperationQueue 有一個(gè)參數(shù) maxConcurrentOperationCount 最大并發(fā)數(shù),用來設(shè)置最多可以讓多少個(gè)任務(wù)同時(shí)執(zhí)行。當(dāng)你把它設(shè)置為 1 的時(shí)候,他不就是串行了嘛!

NSOperationQueue 還有一個(gè)添加任務(wù)的方法,- (void)addOperationWithBlock:(void (^)(void))block; ,這是不是和 GCD 差不多?這樣就可以添加一個(gè)任務(wù)到隊(duì)列中了,十分方便

NSOperation 有一個(gè)非常實(shí)用的功能,那就是添加依賴。比如有 3 個(gè)任務(wù):A: 從服務(wù)器上下載一張圖片,B:給這張圖片加個(gè)水印,C:把圖片返回給服務(wù)器。這時(shí)就可以用到依賴了

operation2.addDependency(operation1) //添加依賴關(guān)系

NSOperation:

BOOL?executing;//判斷任務(wù)是否正在執(zhí)行

BOOL?finished;//判斷任務(wù)是否完成

void?(^completionBlock)(void);//用來設(shè)置完成后需要執(zhí)行的操作

-?(void)cancel;//取消任務(wù)

-?(void)waitUntilFinished;//阻塞當(dāng)前線程直到此任務(wù)執(zhí)行完畢

NSOperationQueue:

NSUInteger?operationCount;//獲取隊(duì)列的任務(wù)數(shù)

-?(void)cancelAllOperations;//取消隊(duì)列中所有的任務(wù)

-?(void)waitUntilAllOperationsAreFinished;//阻塞當(dāng)前線程直到此隊(duì)列中的所有任務(wù)執(zhí)行完畢

[queue?setSuspended:YES];//?暫停queue

[queue?setSuspended:NO];//?繼續(xù)queue


線程同步?

所謂線程同步就是為了防止多個(gè)線程搶奪同一個(gè)資源造成的數(shù)據(jù)安全問題,所采取的一種措施。當(dāng)然也有很多實(shí)現(xiàn)方法.

互斥鎖:給需要同步的代碼塊加一個(gè)互斥鎖,就可以保證每次只有一個(gè)線程訪問此代碼塊。

@synchronized(self) {

//需要執(zhí)行的代碼塊

}

同步執(zhí)行:我們可以使用多線程的知識(shí),把多個(gè)線程都要執(zhí)行此段代碼添加到同一個(gè)串行隊(duì)列,這樣就實(shí)現(xiàn)了線程同步的概念。當(dāng)然這里可以使用 GCD 和 NSOperation 兩種方案

//GCD

//需要一個(gè)全局變量queue,要讓所有線程的這個(gè)操作都加到一個(gè)queue中

dispatch_sync(queue,?^{

NSInteger?ticket?=?lastTicket;

[NSThread?sleepForTimeInterval:0.1];

NSLog(@"%ld?-?%@",ticket,?[NSThread?currentThread]);

ticket?-=?1;

lastTicket?=?ticket;

});

//NSOperation?&?NSOperationQueue

//重點(diǎn):1.?全局的?NSOperationQueue,?所有的操作添加到同一個(gè)queue中

//???????2.?設(shè)置?queue?的?maxConcurrentOperationCount?為?1

//???????3.?如果后續(xù)操作需要Block中的結(jié)果,就需要調(diào)用每個(gè)操作的waitUntilFinished,阻塞當(dāng)前線程,一直等到當(dāng)前操作完成,才允許執(zhí)行后面的。waitUntilFinished?要在添加到隊(duì)列之后!

NSBlockOperation?*operation?=?[NSBlockOperation?blockOperationWithBlock:^{

NSInteger?ticket?=?lastTicket;

[NSThread?sleepForTimeInterval:1];

NSLog(@"%ld?-?%@",ticket,?[NSThread?currentThread]);

ticket?-=?1;

lastTicket?=?ticket;

}];

[queue?addOperation:operation];

[operation?waitUntilFinished];

//后續(xù)要做的事


從其他線程回到主線程的方法:

1. [self performSelectorOnMainThread:@selector(run) withObject:nil waitUntilDone:NO];

2. dispatch_async(dispatch_get_main_queue(), ^{

});

3. [[NSOperationQueue mainQueue] addOperationWithBlock:^{

}];

最后編輯于
?著作權(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),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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