浅谈多线程——NSOperation
iOS中多线程相关方法——NSOperation及其相关类:
NSOperation
NSBlockOperation
NSInvocationOperation
NSOperationQueue
1.NSOperation:一般在使用NSOperation进行线程操作时,不常用该类,而是用他的子类或NSOperationQueue;当然,也可以使用他的block属性创建线程。
1 @interface ViewController () 2 { 3 @public 4 int count; 5 } 6 @end 7 8 @implementation ViewController 9 - (void)viewDidLoad { 10 [super viewDidLoad]; 11 12 NSLog(@"==Start=="); 13 14 count = 0; 15 for (int i = 0; i < 10; i++) { 16 NSOperation *opration = [[NSOperation alloc] init]; 17 opration.completionBlock = ^(){ 18 NSLog(@"%@ = %@", @"operation_block", [NSThread currentThread]); 19 }; 20 // 开启多线程 21 [opration start]; 22 } 23 24 NSLog(@"==End=="); 25 } 26 27 - (void)action:sender{ 28 count ++; 29 NSLog(@"%@[%d] = %@", sender, count, [NSThread currentThread]); 30 } 31 @end
2016-04-18 10:10:42.563 Demo_NSOperation[1461:47803] ==Start==
2016-04-18 10:10:42.564 Demo_NSOperation[1461:47803] ==End==
2016-04-18 10:10:42.564 Demo_NSOperation[1461:47978] operation_block = <NSThread: 0x7fff32602320>{number = 2, name = (null)}
2016-04-18 10:10:42.564 Demo_NSOperation[1461:47979] operation_block = <NSThread: 0x7fff3274a470>{number = 3, name = (null)}
2016-04-18 10:10:42.564 Demo_NSOperation[1461:47982] operation_block = <NSThread: 0x7fff3240a940>{number = 5, name = (null)}
2016-04-18 10:10:42.564 Demo_NSOperation[1461:47984] operation_block = <NSThread: 0x7fff32402e10>{number = 4, name = (null)}
2016-04-18 10:10:42.565 Demo_NSOperation[1461:47978] operation_block = <NSThread: 0x7fff32602320>{number = 2, name = (null)}
2016-04-18 10:10:42.565 Demo_NSOperation[1461:47979] operation_block = <NSThread: 0x7fff3274a470>{number = 3, name = (null)}
2016-04-18 10:10:42.566 Demo_NSOperation[1461:47985] operation_block = <NSThread: 0x7fff32605a70>{number = 6, name = (null)}
2016-04-18 10:10:42.566 Demo_NSOperation[1461:47982] operation_block = <NSThread: 0x7fff3240a940>{number = 5, name = (null)}
2016-04-18 10:10:42.566 Demo_NSOperation[1461:47984] operation_block = <NSThread: 0x7fff32402e10>{number = 4, name = (null)}
2016-04-18 10:10:42.567 Demo_NSOperation[1461:47978] operation_block = <NSThread: 0x7fff32602320>{number = 2, name = (null)}
2.NSBlockOperation:是NSOperation的子类
1 @interface ViewController () 2 { 3 @public 4 int count; 5 } 6 @end 7 8 @implementation ViewController 9 10 - (void)viewDidLoad { 11 [super viewDidLoad]; 12 13 NSLog(@"==Start=="); 14 15 count = 0; 16 for (int i = 0; i < 10; i++) { // 直接使用NSBlockOperation的类方法 17 NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{ 18 NSLog(@"%@ = %@", @"blockOperation", [NSThread currentThread]); 19 }]; 20 21 [blockOperation start]; 22 } 23 24 NSLog(@"==End=="); 25 } 26 27 - (void)action:sender{ 28 count ++; 29 NSLog(@"%@[%d] = %@", sender, count, [NSThread currentThread]); 30 } 31 @end
2016-04-18 12:04:03.893 Demo_NSOperation[2103:104349] ==Start==
2016-04-18 12:04:03.894 Demo_NSOperation[2103:104349] blockOperation = <NSThread: 0x7fb3f3502930>{number = 1, name = main}
2016-04-18 12:04:03.894 Demo_NSOperation[2103:104349] blockOperation = <NSThread: 0x7fb3f3502930>{number = 1, name = main}
2016-04-18 12:04:03.894 Demo_NSOperation[2103:104349] blockOperation = <NSThread: 0x7fb3f3502930>{number = 1, name = main}
2016-04-18 12:04:03.894 Demo_NSOperation[2103:104349] blockOperation = <NSThread: 0x7fb3f3502930>{number = 1, name = main}
2016-04-18 12:04:03.894 Demo_NSOperation[2103:104349] blockOperation = <NSThread: 0x7fb3f3502930>{number = 1, name = main}
2016-04-18 12:04:03.895 Demo_NSOperation[2103:104349] blockOperation = <NSThread: 0x7fb3f3502930>{number = 1, name = main}
2016-04-18 12:04:03.895 Demo_NSOperation[2103:104349] blockOperation = <NSThread: 0x7fb3f3502930>{number = 1, name = main}
2016-04-18 12:04:03.895 Demo_NSOperation[2103:104349] blockOperation = <NSThread: 0x7fb3f3502930>{number = 1, name = main}
2016-04-18 12:04:03.895 Demo_NSOperation[2103:104349] blockOperation = <NSThread: 0x7fb3f3502930>{number = 1, name = main}
2016-04-18 12:04:03.895 Demo_NSOperation[2103:104349] blockOperation = <NSThread: 0x7fb3f3502930>{number = 1, name = main}
2016-04-18 12:04:03.895 Demo_NSOperation[2103:104349] ==End==
1 @interface ViewController () 2 { 3 @public 4 int count; 5 } 6 @end 7 8 @implementation ViewController 9 - (void)viewDidLoad { 10 [super viewDidLoad]; 11 12 NSLog(@"==Start=="); 13 14 count = 0; 15 for (int i = 0; i < 5; i++) { 16 NSBlockOperation *blockOperation = [NSBlockOperation new]; 17 // 使用NSBlockOperation的实例方法 18 [blockOperation addExecutionBlock:^{ 19 NSLog(@"%@ = %@", @"blockOperation1", [NSThread currentThread]); 20 }]; 21 22 [blockOperation addExecutionBlock:^{ 23 NSLog(@"%@ = %@", @"blockOperation2", [NSThread currentThread]); 24 }]; 25 26 [blockOperation addExecutionBlock:^{ 27 NSLog(@"%@ = %@", @"blockOperation3", [NSThread currentThread]); 28 }]; 29 30 [blockOperation start]; 31 } 32 33 NSLog(@"==End=="); 34 } 35 36 - (void)action:sender{ 37 count ++; 38 NSLog(@"%@[%d] = %@", sender, count, [NSThread currentThread]); 39 } 40 @end
2016-04-18 14:07:23.518 Demo_NSOperation[2797:178037] ==Start==
2016-04-18 14:07:23.520 Demo_NSOperation[2797:178037] blockOperation1 = <NSThread: 0x7f9019e02610>{number = 1, name = main}
2016-04-18 14:07:23.520 Demo_NSOperation[2797:178070] blockOperation3 = <NSThread: 0x7f9019f13620>{number = 2, name = (null)}
2016-04-18 14:07:23.520 Demo_NSOperation[2797:178069] blockOperation2 = <NSThread: 0x7f9019c0bf50>{number = 3, name = (null)}
2016-04-18 14:07:23.521 Demo_NSOperation[2797:178037] blockOperation1 = <NSThread: 0x7f9019e02610>{number = 1, name = main}
2016-04-18 14:07:23.521 Demo_NSOperation[2797:178070] blockOperation3 = <NSThread: 0x7f9019f13620>{number = 2, name = (null)}
2016-04-18 14:07:23.521 Demo_NSOperation[2797:178069] blockOperation2 = <NSThread: 0x7f9019c0bf50>{number = 3, name = (null)}
2016-04-18 14:07:23.522 Demo_NSOperation[2797:178037] blockOperation1 = <NSThread: 0x7f9019e02610>{number = 1, name = main}
2016-04-18 14:07:23.522 Demo_NSOperation[2797:178070] blockOperation3 = <NSThread: 0x7f9019f13620>{number = 2, name = (null)}
2016-04-18 14:07:23.522 Demo_NSOperation[2797:178069] blockOperation2 = <NSThread: 0x7f9019c0bf50>{number = 3, name = (null)}
2016-04-18 14:07:23.523 Demo_NSOperation[2797:178037] blockOperation1 = <NSThread: 0x7f9019e02610>{number = 1, name = main}
2016-04-18 14:07:23.523 Demo_NSOperation[2797:178070] blockOperation2 = <NSThread: 0x7f9019f13620>{number = 2, name = (null)}
2016-04-18 14:07:23.523 Demo_NSOperation[2797:178069] blockOperation3 = <NSThread: 0x7f9019c0bf50>{number = 3, name = (null)}
2016-04-18 14:07:23.524 Demo_NSOperation[2797:178037] blockOperation1 = <NSThread: 0x7f9019e02610>{number = 1, name = main}
2016-04-18 14:07:23.524 Demo_NSOperation[2797:178070] blockOperation3 = <NSThread: 0x7f9019f13620>{number = 2, name = (null)}
2016-04-18 14:07:23.524 Demo_NSOperation[2797:178069] blockOperation2 = <NSThread: 0x7f9019c0bf50>{number = 3, name = (null)}
2016-04-18 14:07:23.524 Demo_NSOperation[2797:178037] ==End==
3.NSInvocationOperation:是NSOperation的子类
1 @interface ViewController () 2 { 3 @public 4 int count; 5 } 6 @end 7 8 @implementation ViewController 9 - (void)viewDidLoad { 10 [super viewDidLoad]; 11 12 NSLog(@"==Start=="); 13 14 count = 0; 15 for (int i = 0; i < 5; i++) { 16 // 使用构造方法 17 NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(action:) object:@"invocationOperation"]; 18 // 使用实例方法 19 [invocationOperation setCompletionBlock:^{ 20 NSLog(@"%@ %@", @"iop", [NSThread currentThread]); 21 }]; 22 23 [invocationOperation start]; 24 } 25 26 NSLog(@"==End=="); 27 } 28 29 - (void)action:sender{ 30 count ++; 31 NSLog(@"%@[%d] = %@", sender, count, [NSThread currentThread]); 32 } 33 @end
2016-04-18 14:18:41.245 Demo_NSOperation[2929:183996] ==Start==
2016-04-18 14:18:41.246 Demo_NSOperation[2929:183996] invocationOperation[1] = <NSThread: 0x7fe0c3506ed0>{number = 1, name = main}
2016-04-18 14:18:41.247 Demo_NSOperation[2929:183996] invocationOperation[2] = <NSThread: 0x7fe0c3506ed0>{number = 1, name = main}
2016-04-18 14:18:41.247 Demo_NSOperation[2929:183996] invocationOperation[3] = <NSThread: 0x7fe0c3506ed0>{number = 1, name = main}
2016-04-18 14:18:41.247 Demo_NSOperation[2929:183996] invocationOperation[4] = <NSThread: 0x7fe0c3506ed0>{number = 1, name = main}
2016-04-18 14:18:41.247 Demo_NSOperation[2929:184167] iop <NSThread: 0x7fe0c3704110>{number = 2, name = (null)}
2016-04-18 14:18:41.247 Demo_NSOperation[2929:183996] invocationOperation[5] = <NSThread: 0x7fe0c3506ed0>{number = 1, name = main}
2016-04-18 14:18:41.248 Demo_NSOperation[2929:183996] ==End==
2016-04-18 14:18:41.248 Demo_NSOperation[2929:184170] iop <NSThread: 0x7fe0c3704180>{number = 4, name = (null)}
2016-04-18 14:18:41.247 Demo_NSOperation[2929:184171] iop <NSThread: 0x7fe0c3417940>{number = 3, name = (null)}
2016-04-18 14:18:41.248 Demo_NSOperation[2929:184167] iop <NSThread: 0x7fe0c3704110>{number = 2, name = (null)}
2016-04-18 14:18:41.248 Demo_NSOperation[2929:184177] iop <NSThread: 0x7fe0c36093a0>{number = 5, name = (null)}
无论是NSBlockOperation的类方法还是NSInvocationOperation实例方法都在主线程中执行;而使用addExecutionBlock方法则会在主线程及子线程中运行;使用setCompletionBlock方法则会开辟多线程。
4.NSOperationQueue:并不是NSOperation的子类,但是常与NSOperation搭配使用,加入queue的操作会开辟子线程处理
1 @interface ViewController () 2 { 3 @public 4 int count; 5 } 6 @end 7 8 @implementation ViewController 9 10 - (void)viewDidLoad { 11 [super viewDidLoad]; 12 13 NSLog(@"==Start=="); 14 15 count = 0; 16 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; 17 NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(action:) object:@"operationQueue"]; 18 NSInvocationOperation *operation1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(action:) object:@"operationQueue1"]; 19 NSInvocationOperation *operation2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(action:) object:@"operationQueue2"]; 20 [queue addOperations:@[operation, operation1, operation2] waitUntilFinished:YES]; 21 22 NSLog(@"==End=="); 23 } 24 25 - (void)action:sender{ 26 count ++; 27 NSLog(@"%@[%d] = %@", sender, count, [NSThread currentThread]); 28 } 29 @end
2016-04-18 15:03:12.566 Demo_NSOperation[3259:201876] ==Start==
2016-04-18 15:03:12.567 Demo_NSOperation[3259:202092] operationQueue2[2] = <NSThread: 0x7fa791c1fe60>{number = 4, name = (null)}
2016-04-18 15:03:12.567 Demo_NSOperation[3259:202072] operationQueue[3] = <NSThread: 0x7fa791e05a80>{number = 3, name = (null)}
2016-04-18 15:03:12.567 Demo_NSOperation[3259:202070] operationQueue1[1] = <NSThread: 0x7fa791d48370>{number = 2, name = (null)}
2016-04-18 15:03:12.568 Demo_NSOperation[3259:201876] ==End==
NSOperation中含有@property NSOperationQueuePriority queuePriority;和@property NSQualityOfService qualityOfService;的枚举属性,可选择线程的优先级以及子线程开辟方式。