一、NSOperation的介紹
1、NSOperation的作用
配合使用NSOperation和NSOperationQueue實現多線程編程
2、實現多線程的具體步驟
1)將需要執行的操作封裝到一個NSOperation對象中
2)將NSOperation對象添加到NSOperationQueue中
3)系統自動將NSOperationQueue中的NSOperation取出來,並且將封裝的操作放到一條新線程中執行
3、NSOperation十個抽象類,並沒有封裝操作的能力,必須使用它的子類
4、子類的三種形式
1)NSInvocationOperation
2)NSBlockOpera
3)自定義繼承自NSOperation的子類,實現內部相應的方法
二、結合代碼
1、NSInvocationOperation的使用
1)沒有添加到隊列
- (void)useNSInvocationOperation
{
//1.封裝操作
NSInvocationOperation * operation1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(invocationTask) object:nil];
//開始執行
[operation1 start];
NSInvocationOperation * operation2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(invocationTask2) object:nil];
[operation2 start];
}
- (void)invocationTask
{
NSLog(@"invocationTask,%@",[NSThread currentThread]);
}
- (void)invocationTask2
{
NSLog(@"invocationTask2,%@",[NSThread currentThread]);
}
打印結果:
2016-03-14 17:53:59.638 NSoperation[3071:257804] invocationTask,<NSThread: 0x7f86fad06cb0>{number = 1, name = main}
2016-03-14 17:53:59.639 NSoperation[3071:257804] invocationTask2,<NSThread: 0x7f86fad06cb0>{number = 1, name = main}
注意事項:結果中可以看出如果沒有放到隊列中,默認同步執行,都在主線程。
2)添加到隊列
- (void)useNSInvocationOperation
{
//1.封裝操作
NSInvocationOperation * operation1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(invocationTask) object:nil];
NSInvocationOperation * operation2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(invocationTask2) object:nil];
//2.創建隊列
NSOperationQueue * queue = [[NSOperationQueue alloc]init];
queue.maxConcurrentOperationCount = 2;//最大線程數:2-3最好
//3.添加操作到隊列
[queue addOperation:operation1];
[queue addOperation:operation2];
}
- (void)invocationTask
{
NSLog(@"invocationTask,%@",[NSThread currentThread]);
}
- (void)invocationTask2
{
NSLog(@"invocationTask2,%@",[NSThread currentThread]);
}
打印結果:
2016-03-14 17:57:33.192 NSoperation[3083:261277] invocationTask2,<NSThread: 0x7fd9b8f07ee0>{number = 2, name = (null)}
2016-03-14 17:57:33.192 NSoperation[3083:261278] invocationTask,<NSThread: 0x7fd9b8e13210>{number = 3, name = (null)}
根據打印結果可以看出加入隊列之後,系統又開啟了兩條線程。
2、NSBlockOperation的使用
//1.封裝操作
NSBlockOperation * operation1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"NSBlockOperation---operation1,%@",[NSThread currentThread]);
}];
//2.添加更多的操作
[operation1 addExecutionBlock:^{
NSLog(@"NSBlockOperation---%@",[NSThread currentThread]);
}];
[operation1 start];
輸出結果:
2016-03-14 18:04:22.577 NSoperation[3105:266124] NSBlockOperation---operation1,<NSThread: 0x7f9e7850a1c0>{number = 1, name = main}
2016-03-14 18:04:22.577 NSoperation[3105:266206] NSBlockOperation---<NSThread: 0x7f9e785a4eb0>{number = 2, name = (null)}
注意事項:只要NSBlockOperation的封裝操作數大於1,就會執行一部操作
3、給線程添加依賴
- (void)useNSInvocationOperation
{
//1.封裝操作
NSInvocationOperation * operation1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(invocationTask) object:nil];
NSInvocationOperation * operation2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(invocationTask2) object:nil];
NSInvocationOperation * operation3 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(invocationTask3) object:nil];
//2.創建隊列
NSOperationQueue * queue = [[NSOperationQueue alloc]init];
queue.maxConcurrentOperationCount = 3;//最大線程數:2-3最好
//2.1設置依賴
[operation1 addDependency:operation3];
[operation3 addDependency:operation2];
//3.添加操作到隊列
[queue addOperation:operation1];
[queue addOperation:operation2];
[queue addOperation:operation3];
}
- (void)invocationTask
{
NSLog(@"invocationTask,%@",[NSThread currentThread]);
}
- (void)invocationTask2
{
NSLog(@"invocationTask2,%@",[NSThread currentThread]);
}
- (void)invocationTask3
{
NSLog(@"invocationTask3,%@",[NSThread currentThread]);
}
輸出結果:
2016-03-14 18:12:21.066 NSoperation[3135:272293] invocationTask2,<NSThread: 0x7f845a54e500>{number = 2, name = (null)}
2016-03-14 18:12:21.067 NSoperation[3135:272293] invocationTask3,<NSThread: 0x7f845a54e500>{number = 2, name = (null)}
2016-03-14 18:12:21.067 NSoperation[3135:272293] invocationTask,<NSThread: 0x7f845a54e500>{number = 2, name = (null)}
根據結果可以看出先執行的2又執行的3最後執行的1,並沒有根據添加到隊列的順序執行。
4、設置線程的優先級
1)operation1.queuePriority = NSOperationQueuePriorityHigh;
2)優先級的取值
NSOperationQueuePriorityVeryLow = -8L,
NSOperationQueuePriorityLow = -4L,
NSOperationQueuePriorityNormal = 0,
NSOperationQueuePriorityHigh = 4,
NSOperationQueuePriorityVeryHigh = 8