1.简介:
1.1. iOS有3种实现多线程编程的方式:
(1)NSThread
(2)NSOperation
(3)GCD
这3种方式从上到下抽象程度由低到高,抽象度越高,使用越简单,苹果越推荐
1.2. 3种方式的优缺点:
(1)NSThread:
优点:比其他两个更加轻量级,抽象程度也最低
缺点:需要自己管理线程的生命周期、线程同步等操作
(2)NSOperation:
优点:不需要关心线程管理、数据同步等,可以把精力放在自己需要执行的操作上
(3)GCD:
苹果开发的一个多核编程的解决方案,iOS4.0之后开始使用
2.NSThread使用:
NSThread有3种创建方法:
(1)+ (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument;
(2)NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(download:) object:kURL];
[thread start];
(3)- (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg
前两种方法是NSThread的方法,一个类方法,一个实例方法;第三种方法是NSObject的实例方法,不是显示地创建线程
3.NSOperation使用:
NSOperation是个抽象类,要使用它必须子类化它
使用NSOperation有2种方式:
(1)使用系统已经定义好的NSOperation的子类:NSBlockOperation、NSInvocationOperation;
(2)自己子类化NSOperation并实现它的main方法。
创建好NSOperation的子类后,将其加入NSOperationQueue中,操作队列就会启动并执行操作。
4.GCD使用:
4.1. GCD的dispatch queue分为3种:
(1)用户创建的队列:dispatch_queue_create()
(2)主线程队列(串行):dispatch_get_main_queue()
(3)全局队列(并发):dispatch_get_global_queue(0, 0)
4.2. GCD常用方法:
(1)dispatch_async:异步操作
以下是下载图片的代码
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:kURL]];
if (data) {
dispatch_async(dispatch_get_main_queue(), ^{
_myImageView.image = [UIImage imageWithData:data];
});
}
});
(3)dispatch_group_async:异步操作
该方法可以监听一组任务是否完成,完成后通知进行其他操作。下面的代码实现,3张图片下载完成后,弹出警告框提示
dispatch_queue_t globalQ = dispatch_get_global_queue(0, 0);
dispatch_queue_t mainQ = dispatch_get_main_queue();
dispatch_group_t group = dispatch_group_create();
// 线程1
dispatch_group_async(group, globalQ, ^{
NSLog(@"线程1");
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:kURL]];
if (data) {
dispatch_async(mainQ, ^{
_myImageView1.image = [UIImage imageWithData:data];
});
}
});
// 线程2
dispatch_group_async(group, globalQ, ^{
NSLog(@"线程2");
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:kURL]];
if (data) {
dispatch_async(mainQ, ^{
_myImageView2.image = [UIImage imageWithData:data];
});
}
});
// 线程3
dispatch_group_async(group, globalQ, ^{
NSLog(@"线程3");
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:kURL]];
if (data) {
dispatch_async(mainQ, ^{
_myImageView3.image = [UIImage imageWithData:data];
});
}
});
dispatch_group_notify(group, mainQ, ^{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:@"图片下载完成" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
[alertView show];
});
(3)dispatch_barrier_async:(异步操作)
它前面的任务完成后它才开始执行,他后面的任务也要等着它完成后才执行
(4)dispatch_apply
执行你的代码块N次