一、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