一、NSThread线程
优点:
NSThread 比其他两个轻量级、使用方便、简洁。
缺点:
①需要自己管理线程的生命周期。
②线程同步,线程同步对数据的加锁会有一定的系统开销
NSThread线程的使用:
启动一个线程
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(myThreadTask) object:nil];
thread.name=@"sum";
[thread start]
停止线程
[thread cancel];
thread = nil;
注意:停止线程的并不是直接杀死线程,而是设置了个标记
-(void) myThreadTask{
@autoreleasepool {
NSLog(@"Thread Entry Point");
while ([[NSThread currentThread] isCancelled] == NO){
[NSThread sleepForTimeInterval:10];
NSLog(@"Thread Loop");
}
NSLog(@"Thread Finished");
}
}
还有一类用法如下:
[NSThread detachNewThreadSelector:@selector(bigDemo) toTarget:self withObject:nil];
二、NSOperation
优点:
① 底层实现自GCD,相对高效
② 内部线程池可以更好的管理子线程
③可以设置线程执行的优先级和依赖关系
NSOperation的用法:
1.无依赖关系
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^(){
NSLog(@"执行第1次操作,线程:%@", [NSThread currentThread]);
}];
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^(){
NSLog(@"执行第2次操作,线程:%@", [NSThread currentThread]);
}];
[queue addOperation:operation1];
[queue addOperation:operation2];
2.设置依赖关系
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^(){
NSLog(@"执行第1次操作,线程:%@", [NSThread currentThread]);
}];
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^(){
NSLog(@"执行第2次操作,线程:%@", [NSThread currentThread]);
}];
// operation1依赖于operation2
[operation1 addDependency:operation2]; //那么2先执行,接下来1才能执行
[queue addOperation:operation1];
[queue addOperation:operation2];
3.设置线程最大并发数量,一般并发量取决于cpu核心数
queue.maxConcurrentOperationCount = 3;
三、GCD多线程
GCD的底层依然是用线程实现,让程序平行排队的特定任务,根据可用的处理资源,安排他们在任何可用的处理器核心上执行任务。
优点:
①高效、可以选择各种队列
②可扩展性高
缺点:
①无法实现多线程同步,线程同步需要借助信号量来实现
②无法直接取消指定的任务
GCD使用场景一:
单例
+ (instancetype)defaultViewController {
static ViewController *vc = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
vc = [[ViewController alloc] init];
});
return vc;
}
图片异步加载的实现
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
NSURL*url = [NSURLURLWithString:@"http://img5.netease.com/img/20151030124521.jpg"];
NSData*data = [NSDatadataWithContentsOfURL:url];
UIImage*image = [UIImageimageWithData:data];
// GCD返回主线程UI赋值
dispatch_sync(dispatch_get_main_queue(), ^{
self.imageView.image= image;
});
});
并发
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//请求1
NSLog(@"Request_1");
});
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//请求2
NSLog(@"Request_2");
});
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//请求3
NSLog(@"Request_3");
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
//界面刷新
NSLog(@"任务均完成,刷新界面");
});
通过barrier控制并发量
barrier:表示栅栏,当在并发队列里面使用栅栏时候,栅栏之前的并发任务开始并发执行,执行完毕后,执行栅栏内的任务,等栅栏任务执行完毕后,再并发执行栅栏后的任务。
dispatch_queue_t concurrentQueue = dispatch_queue_create("my.concurrent.queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(concurrentQueue, ^(){
NSLog(@"dispatch-1");
});
dispatch_async(concurrentQueue, ^(){
NSLog(@"dispatch-2");
});
dispatch_barrier_async(concurrentQueue, ^(){
NSLog(@"dispatch-barrier");
});
dispatch_async(concurrentQueue, ^(){
NSLog(@"dispatch-3");
});
dispatch_async(concurrentQueue, ^(){
NSLog(@"dispatch-4");
});
四、向主线程发送消息
普通对象
MyThread *newThread = [[MyThread alloc] init];
NSObject * plainObject = newThread;
[plainObject performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:YES]
NSOperation
NSBlockOperation *b=[NSBlockOperation blockOperationWithBlock:^{
NSLog(@"%@",[NSThread currentThread]);
}];
[[NSOperationQueue mainQueue]addOperation:b];
dispatch
dispatch_sync(dispatch_get_main_queue(), ^{
self.imageView.image= image;
});
来源:oschina
链接:https://my.oschina.net/u/2256215/blog/1607252