NSOperation 和 NSOperationQueue 分別對應(yīng) GCD 的 任務(wù) 和 隊列
NSOperation
//1.創(chuàng)建NSInvocationOperation對象
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run) object:nil];
//2.開始執(zhí)行
[operation start];
NSBlockOperation 還有一個方法:addExecutionBlock: 橘原,通過這個方法可以給 Operation 添加多個執(zhí)行 Block。這樣 Operation 中的任務(wù) 會并發(fā)執(zhí)行作烟,它會 在主線程和其它的多個線程 執(zhí)行這些任務(wù)
//1.創(chuàng)建NSBlockOperation對象
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@
"%@"
, [NSThread currentThread]);
}];
//添加多個Block
for
(NSInteger i = 0; i < 5; i++) {
[operation addExecutionBlock:^{
NSLog(@
"第%ld次:%@"
, i, [NSThread currentThread]);
}];
}
//2.開始任務(wù)
[operation start];
NSOperationQueue
我們可以調(diào)用一個 NSOperation 對象的 start() 方法來啟動這個任務(wù)修赞,但是這樣做他們默認是 同步執(zhí)行 的带污。就算是 addExecutionBlock 方法体箕,也會在 當(dāng)前線程和其他線程 中執(zhí)行,也就是說還是會占用當(dāng)前線程杈笔。這是就要用到隊列 NSOperationQueue 了
主隊列
細心的同學(xué)就會發(fā)現(xiàn)闪水,每套多線程方案都會有一個主線程(當(dāng)然啦,說的是iOS中桩撮,像 pthread 這種多系統(tǒng)的方案并沒有敦第,因為 UI線程 理論需要每種操作系統(tǒng)自己定制)。這是一個特殊的線程店量,必須串行芜果。所以添加到主隊列的任務(wù)都會一個接一個地排著隊在主線程處理。
1
2
3
4
//OBJECTIVE-C
NSOperationQueue *queue = [NSOperationQueue mainQueue];
//Objective-C
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
}];
其他隊列
因為主隊列比較特殊融师,所以會單獨有一個類方法來獲得主隊列右钾。那么通過初始化產(chǎn)生的隊列就是其他隊列了,因為只有這兩種隊列旱爆,除了主隊列舀射,其他隊列就不需要名字了。
//1.創(chuàng)建一個其他隊列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
//2.創(chuàng)建NSBlockOperation對象
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@
"%@"
, [NSThread currentThread]);
}];
//3.添加多個Block
for
(NSInteger i = 0; i < 5; i++) {
[operation addExecutionBlock:^{
NSLog(@
"第%ld次:%@"
, i, [NSThread currentThread]);
}];
}
//4.隊列添加任務(wù)
[queue addOperation:operation];
NSOperation 有一個非常實用的功能怀伦,那就是添加依賴脆烟。比如有 3 個任務(wù):A: 從服務(wù)器上下載一張圖片,B:給這張圖片加個水印房待,C:把圖片返回給服務(wù)器邢羔。這時就可以用到依賴了:
//1.任務(wù)一:下載圖片
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@
"下載圖片 - %@"
, [NSThread currentThread]);
[NSThread sleepForTimeInterval:1.0];
}];
//2.任務(wù)二:打水印
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@
"打水印 - %@"
, [NSThread currentThread]);
[NSThread sleepForTimeInterval:1.0];
}];
//3.任務(wù)三:上傳圖片
NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@
"上傳圖片 - %@"
, [NSThread currentThread]);
[NSThread sleepForTimeInterval:1.0];
}];
//4.設(shè)置依賴
[operation2 addDependency:operation1];
//任務(wù)二依賴任務(wù)一
[operation3 addDependency:operation2];
//任務(wù)三依賴任務(wù)二
//5.創(chuàng)建隊列并加入任務(wù)
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperations:@[operation3, operation2, operation1] waitUntilFinished:NO];
其他方法
以上就是一些主要方法, 下面還有一些常用方法需要大家注意:
NSOperation
1
2
3
4
5
BOOL executing;
//判斷任務(wù)是否正在執(zhí)行
BOOL finished;
//判斷任務(wù)是否完成
void (^completionBlock)(void);
//用來設(shè)置完成后需要執(zhí)行的操作
(void)cancel;
//取消任務(wù)(void)waitUntilFinished;
//阻塞當(dāng)前線程直到此任務(wù)執(zhí)行完畢
NSOperationQueue
1
2
3
4
5
NSUInteger operationCount;
//獲取隊列的任務(wù)數(shù)
(void)cancelAllOperations;
//取消隊列中所有的任務(wù)(void)waitUntilAllOperationsAreFinished;
//阻塞當(dāng)前線程直到此隊列中的所有任務(wù)執(zhí)行完畢
[queue setSuspended:YES];
// 暫停queue
[queue setSuspended:NO];
// 繼續(xù)queue