前面已經提到多線程編程的多個實現方式。其中,GCD是開發中最常見的多線程編程實現方案;我們都知道,GCD是純C語言的,可跨平臺使用、功能強大;其實,蘋果也為我們提供了一套面向對象的實現多線程的方案,那就是NSOperation.
NSOperation介紹:
NSOperation:同CAAnimation核心動畫一樣,都是抽象類,并不具備封裝操作的能力,必須使用其子類。
使用NSOperation子類的方式有3種:
使用NSInvocationOperation
使用NSBlockOperation
自定義子類繼承NSOperation,實現內部相應的方法(main方法)
操作隊列NSOperationQueue:
想要利用NSOperation實現多線程編程,我們需要借助NSOperationQueue這個類。就像在GCD中,我們需要使用全局隊列或創建新的并發隊列一樣。
1.NSOperation和NSOperationQueue多線程編程
a.NSInvocationOperation與NSOperationQueue的使用
//1.創建操作,封裝任務
/*
第一個參數:目標對象 self
第二個參數:調用方法的名稱
第三個參數:前面方法需要接受的參數 nil
*/
NSInvocationOperation *op1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(download1) object:nil];
//2.創建隊列
/*
NSOperation:
主隊列: [NSOperationQueue mainQueue] 和GCD中的主隊列一樣,串行隊列
非主隊列: [[NSOperationQueue alloc]init] 非常特殊(同時具備并發和串行的功能,最大并發數為1時,就是串行)
//默認情況下,非主隊列是并發隊列
*/
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
//3.添加操作到隊列中
[queue addOperation:op1]; //內部已經調用了[op1 start]
b. NSBlockOperation
//1.創建操作
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"1----%@",[NSThread currentThread]);
}];
//2.創建隊列
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
//3.添加操作到隊列
[queue addOperation:op1];
// 上面的可以組合在一起寫
//簡便方法
//1)創建操作,2)添加操作到隊列中
[queue addOperationWithBlock:^{
NSLog(@"1---%@",[NSThread currentThread]);
}];
c.自定義繼承自NSOperation的操作
//.h文件
#import <Foundation/Foundation.h>
@interface CustomerOperation : NSOperation
@end
//.m文件
#import "CustomerOperation.h"
@implementation CustomerOperation
//告知要執行的任務是什么
-(void)main
{
NSLog(@"main---%@",[NSThread currentThread]);
}
@end
2.對隊列的操作:開始,繼續,暫停與取消
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
[queue addOperationWithBlock:^{
NSLog(@"操作一");
}];
[queue addOperationWithBlock:^{
NSLog(@"操作二");
}];
[queue addOperationWithBlock:^{
NSLog(@"操作三");
}];
[queue addOperationWithBlock:^{
NSLog(@"操作四");
}];
// 在GCD中,我們把要執行的代碼稱任務,在這里我們稱操作,其實都是一樣的。把操作添加到隊列中相當于開始執行該操作
// [queue setSuspended:YES]; // 暫停該隊列中的操作,當前正在執行的任務執行完后暫停
// [queue setSuspended:NO];// 繼續該隊列中的操作
//該方法內部調用了所有操作的cancel方法
// [queue cancelAllOperations];// 取消所有的操作,取消的是隊列中還沒有執行的操作,取消后不可以繼續執行
3.對NSOperation(操作)的操作:依賴和監聽
//1.創建隊列
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
NSOperationQueue *queue2 = [[NSOperationQueue alloc]init];
//2.封裝操作
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"1---%@",[NSThread currentThread]);
}];
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"2---%@",[NSThread currentThread]);
}];
NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"3---%@",[NSThread currentThread]);
}];
NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"4---%@",[NSThread currentThread]);
}];
//操作監聽
op3.completionBlock = ^{
NSLog(@"++++客官,來看我吧------%@",[NSThread currentThread]);
};
//添加操作依賴
//注意點:不能循環依賴
//可以跨隊列依賴
[op1 addDependency:op4];
// [op4 addDependency:op1];
[op2 addDependency:op3];
//添加操作到隊列
[queue addOperation:op1];
[queue addOperation:op2];
[queue addOperation:op3];
[queue2 addOperation:op4];
4.NSOperation中的線程間通信
// GCD中是這樣嵌套的
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"在子線程中執行的任務");
// 回到主線程執行
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"在主線程中執行的任務");
});
});
// NSOperation中,我們同樣是采用嵌套
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
//1.2 封裝操作
NSBlockOperation *download = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"在子線程中執行的任務");
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
NSLog(@"在主線程中執行的任務");
}];
}];
//2.添加操作到隊列
[queue addOperation:download];
到此,多線程的基本知識就寫完了,謝謝大家的閱讀。