简介
iOS有三种多线程编程技术,分别是:
《1. NSThread
《2 Cocoa NSOperation
《3 GCD(全称:Grand Central Dispatch)
这三种编程方式从上到下,抽象度层次是从低到高,抽象度越高的使用越简单,也是Apple最推荐的。
三种方式的优缺点:
- NSThread
-优点:NSThread 比其他两个轻量级,使用简单
-缺点:需要自己管理线程的生命周期、线程同步、加锁、睡眠以及唤醒等。线程同步对对数据的加锁会有一定的影响
- NSOperation:
- 不需要关心线程管理,数据同步的事情,可以把精力放在自己需要执行的操作上。
- NSOperation是面向对象的
- GCD:
- Grand Central Dispatch是由苹果开发的一个多核编程的解决方案,iOS4.0之后才开始使用,
- GCD是基于C语言的。
3. NSThread
NSThread的三种调用方法:
NSThread *mythread = [[NSThread alloc]initWithtarget:self selector:(mythreadAction:) object:nil];
[self performSelectorInBackground:@selector:(mythreadAction:) withObject:nil];
[NSThread detachNewThreadSelector:(myThreadAction:) toTarget:self withObject:nil];
4. 使用NSThread管理线程的主要步骤:
《1 声明一个NSCondition同步锁
《2 声明若干个NSThread子线程
《3 指定NSThread子线程的目标执行方法(可以在构造函数中指定)
《4 设置子线程的名称
《5 star启动子线程
5. 实例代码:
//创建一个进程锁,实现线程同步
self.condition(NSCondition) = [[NSCondition alloc] init];
//创建线程1
_thread_1=[[NSThread alloc]initWithTarget:self selector:@selector(run) object:nil];
[_thread_1 setName:@"thread_1"];
[_thread_1 start];
//创建线程2
_thread_2=[[NSThread alloc]initWithTarget:self selector:@selector(run) object:nil];
[_thread_2 setName:@"thread_2"];
[_thread_2 start];
#pragma mark--线程执行方法
-(void)run{
//进程上锁
[_condition lock];
NSLog(@"运行的线程名:%@",[[NSThread currentThread]name]);
if ([[[NSThread currentThread]name] isEqualToString:@"thread_1"]) {
NSLog(@"111");
NSURL *imageUrl_1=[NSURL URLWithString:@"http://t.beauty-soft.net/upload/ceiba20130224_014522_8679.jpg"];
NSData *data_1=[NSData dataWithContentsOfURL:imageUrl_1];
UIImage *image_1=[UIImage imageWithData:data_1];
UIImageView *imageView_1=[[UIImageView alloc] initWithImage:image_1];
imageView_1.frame=CGRectMake(60, 20, 200, 200);
[self.view addSubview:imageView_1];
[imageView_1 release];
}else if([[[NSThread currentThread]name] isEqualToString:@"thread_2"]){
NSLog(@"222");
NSURL *imageUrl_2=[NSURL URLWithString:@"http://t.beauty-soft.net/upload/ceiba20120704_121437_3455.jpg"];
NSData *data_2=[NSData dataWithContentsOfURL:imageUrl_2];
UIImage *image_2=[UIImage imageWithData:data_2];
UIImageView *imageView_2=[[UIImageView alloc] initWithImage:image_2];
imageView_2.frame=CGRectMake(60, 250, 200, 200);
[self.view addSubview:imageView_2];
[imageView_2 release];
}
//解锁
[_condition unlock];
}
6. NSOperationQueue类
如果需要让线程同时并行运行多个,可以将线程加入队列(Queue)中,NSOperationQueue类就是一个线程队列管理类,他提供了线程并行、队列的管理。可以认为NSOperationQueue就是一个线程管理器,通过addOperations方法,我们可以一次性把多个(数组形式)线程添加到队列中。同时,NSOperationQueue允许通过setMaxConcurrentOperationCount方法设置队列的并行(同一时间)运行数量。NSOperationQueue的使用步骤如下:
1)声明一个NSOperationQueue对象
2)声明若干个NSInvocationOperation子线程对象,并指定回调方法;
3)将NSInvocationOperation子线程添加到数组;
4)把数组赋给NSOperationQueue类中的addOperations方法;
5) 实现回调方法;
6)在回调方法中实现performSelectorOnMainThread方法,更新主线程上的界面UI元素。
队列及操作:
NSOperationQueue有两种不同类型的队列:主队列和自定义队列.
主队列运行在主线程上,自定义队列在后台执行.
队列处理的任务是NSOperation的子类:NSInvocationOperation 和 NSBlockOperation.
NSOperation的基本使用步骤:
定义操作队列 --> 定义操作 -->将操作添加到队列.
提示:
一旦将操作添加到队列,操作就会立即被调度执行.
NSInvocationOperation(调度操作)
1> 定义队列:
1
|
self.myQueue = [[NSOpertaionQueue alloc] init];
|
2> 操作调用的方法:
1
2
3
4
|
-(
void
)operationAction:(id)obj
{
NSLog(@
"%@----obj : %@ "
,[NSThread currentThread], obj);
};
|
3> 定义操作并添加到队列:
1
2
3
|
NSInvocationOperation *op = [[NSInvocationOperation alloc]
initWithTarget:self selector:@selector(operationAction:) object:@(i)];
[self.myQueue addOperation:op]
|
提示:需要准备一个被调度的方法,并且能够接收一个参数.
NSBlockOperation(块操作)
定义操作并添加到队列:
1
2
3
4
|
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
[self operationAction:@
"Block Operation"
];
}];
[self.myQueue addOperation:op];
|
NSBlockOperation比NSInvocationOperation更加灵活;
设置操作的依赖关系:
利用 " addDependency "可以指定操作之间彼此的依赖关系(执行先后顺序),但是注意不要出现循环依赖.
设置同时并发的线程数量:
1
|
[self.myQueue setMaxConcurrentOperationCount:2];
|
6. NSOperaionQueue的实例代码:
_opeartionQueue=[[NSOperationQueue alloc] init];
//队列最大同时运行数量
[_opeartionQueue setMaxConcurrentOperationCount:1];
tags=20;
//创建线程1
NSInvocationOperation *invocationOpearation_1=[[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run:) object:@"http://t.beauty-soft.net/upload/ceiba20130224_014522_8679.jpg"] autorelease];
//创建线程2
NSInvocationOperation *invocationOpearation_2=[[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run:) object:@"http://t.beauty-soft.net/upload/ceiba20120704_121437_3455.jpg"] autorelease];
NSArray *array=@[invocationOpearation_1,invocationOpearation_2];
//把程序添加到管理器中
[_opeartionQueue addOperations:array waitUntilFinished:YES];