在iOS开发线程操作时,一般方法名决定是否开启新线程(async,sync),队列类型(全局队列,串行队列)决定开启多少条线程
1.快速线程调用
*开启后台线程执行任务
[self performSelectorInBackground:@selector(test) withObject:nil];
*回到主线程执行任务
[self performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:YES];
2.GCD : 依赖队列执行
1> 队列类型
* 全局队列 * 所有添加到全局队列中的任务都是并发执行(同时执行,可能会开启多个线程) * dispatch_get_global_queue * 串行队列 * 所有添加到串行队列中的任务都是按顺序执行(开一条线程) * dispatch_queue_create("myqueue", 0); * 主队列 * 所有添加到主队列中的任务都是在主线程中执行的(跟方法名没有关系) * dispatch_get_main_queue |
2> 同步还是异步,取决于方法名(不影响主队列,影响全局队列、串行队列)
* 同步:dispatch_sync,在当前线程执行任务,不会开启新的线程
* 异步:dispatch_async,在其他线程执行任务,会开启新的线程
3.NSOperation\NSOperationQueue
1> 使用步骤
* 创建NSOperation
* 添加NSOperation到NSOperationQueue
2> 优点
* 更加面向对象 * 可以控制最大并发数 maxConcurrentOperationCount * 添加任务(Operation)之间的依赖 addDependency */ #import "XMQViewController.h" @interface XMQViewController () { NSOperationQueue *_queue; } @end @implementation XMQViewController - (void)viewDidLoad { [super viewDidLoad]; _queue = [[NSOperationQueue alloc] init]; // 控制最大并发数,最多同时执行3条线程 _queue.maxConcurrentOperationCount = 3; // 回到主线程 // [self test]; // 线程监听 // [self gcd_group]; // GCD线程依赖 // [self gcd_barrier]; // 循环执行 [self gcd_apply]; // 全局队列 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 串行队列 // dispatch_queue_t queue2 = dispatch_queue_create("myqueue", 0); dispatch_async(queue, ^{ // 耗时操作 NSLog(@"这是一个异步线程---%@", [NSThread currentThread]); }); } - (IBAction)click { NSOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"operation---%@", [NSThread currentThread]); }]; NSOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"operation2---%@", [NSThread currentThread]); }]; // 该方法默认在主线程执行 // [operation start]; // 加入队列会在异步线程执行 [_queue addOperation:operation]; [_queue addOperation:operation2]; // 设置线程依赖 (operation2依赖于operation,operation执行完以后,才能执行operation2) [operation addDependency:operation2]; } // 延时执行某条线程 - (IBAction)click2 { // 全局队列 // dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 串行队列 dispatch_queue_t queue2 = dispatch_queue_create("myqueue", 0); double delayInSeconds = 5.0; dispatch_time_t delayInNanoSeconds =dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); dispatch_after(delayInNanoSeconds, queue2, ^{ NSLog(@"延迟执行"); }); } // dispatch_group_async(异步方法)可以实现监听一组任务是否完成,完成后得到通知执行其他的操作(比如通知用户下载完成,显示UI等) - (void)gcd_group { dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group, queue, ^{ [NSThread sleepForTimeInterval:1]; NSLog(@"group1"); }); dispatch_group_async(group, queue, ^{ [NSThread sleepForTimeInterval:2]; NSLog(@"group2"); }); dispatch_group_async(group, queue, ^{ [NSThread sleepForTimeInterval:3]; NSLog(@"group3"); }); dispatch_group_notify(group, dispatch_get_main_queue(), ^{ NSLog(@"updateUI"); }); } // dispatch_barrier_async 是在前面的任务执行结束后才执行,而且后面的任务必须等它执行完成之后才会执行 - (void)gcd_barrier { dispatch_queue_t queue = dispatch_queue_create("myqueue", DISPATCH_QUEUE_CONCURRENT); dispatch_async(queue, ^{ [NSThread sleepForTimeInterval:2]; NSLog(@"dispatch_async1"); }); dispatch_async(queue, ^{ [NSThread sleepForTimeInterval:4]; NSLog(@"dispatch_async2"); }); dispatch_barrier_async(queue, ^{ NSLog(@"dispatch_barrier_async"); [NSThread sleepForTimeInterval:4]; }); dispatch_async(queue, ^{ [NSThread sleepForTimeInterval:2]; NSLog(@"dispatch_async3"); }); } // dispatch_apply 执行某个代码片段N次 - (void)gcd_apply { dispatch_queue_t queue = dispatch_queue_create("myqueue", DISPATCH_QUEUE_PRIORITY_DEFAULT); dispatch_apply(10, queue, ^(size_t index) { NSLog(@"循环执行10次"); }); } // 回到主线程 - (void)test { UIImage *image = nil; [self performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:YES]; dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"更新UI界面---%@", [NSThread currentThread]); }); } @end |