NSOperation基本使用
- NSOperation基于GCD的面向对象的封装
- NSOperation配合NSOperationQueue也能实现多线程编程
- 先将需要执行的操作封装到NSOperation中
- 然后将NSOperation添加到NSOperationQueue中
- 系统会自动将NSOperationQueue中的 NSOperation取出来
- 将NSOperation中的操作自动放到一条线程中去执行
NSOperation是个抽象类没有封装操作的能力,一般都是用它的子类去封装需要执行的操作
代码
NSInvocationOperation * op = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(run) object:nil];
//执行操作
[op start];
- (void)run
{
//当前线程为主线程 因为op没有加到队列里面
NSLog(@"%@",[NSThread currentThread]);
}
NSBlockOperation * op = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"1---%@",[NSThread currentThread]);//主线程
}];
//添加额外任务(在子线程中执行)
[op addExecutionBlock:^{
NSLog(@"2---%@",[NSThread currentThread]);
}];
[op addExecutionBlock:^{
NSLog(@"3---%@",[NSThread currentThread]);
}];
[op start];
NSOperationQueue
队列类型
- 主队列:[NSOperationQueue mainQueue];
- 其他队列:[[NSOperationQueue alloc]init];(包含串行和并发功能)
- 添加到队列中的任务会自动放到子线程
GCD队列类型
- 并发队列:全局队列、自己创建的
- 串行队列:主队列、自己创建的
代码
//创建队列 并发队列
NSOperationQueue * queue = [[NSOperationQueue alloc]init];
//设置最大并发数 如果是1就是串行队列
queue.maxConcurrentOperationCount = 3;
suspended = YES;//线程挂起 为NO时回复队列 继续执行
[queue cancelAllOperations];//取消所有线程的执行 相当调用所有线程的cancel方法
#注意:如果是线程正在执行中你暂停线程或者取消线程时 当前线程是不会暂停的 会执行完毕当前线程后才会停止后面的线程
#注意:如果是自定义NSOperation 要不断的判断外面有没有取消你
#建议:执行完一段操作判断一下时候取消了线程
//创建操作任务
NSInvocationOperation * op1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(downLoad1) object:nil];
NSInvocationOperation * op2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(downLoad2) object:nil];
NSBlockOperation * op3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"downLoad3--%@",[NSThread currentThread]);
}];
[op3 addExecutionBlock:^{
NSLog(@"downLoad1--%@",[NSThread currentThread]);
}];
[op3 addExecutionBlock:^{
NSLog(@"downLoad1--%@",[NSThread currentThread]);
}];
//添加操作到队列中
[queue addOperation:op1];//只要添加到队列中 会自动开启线程
[queue addOperation:op2];
[queue addOperation:op3];
线程的依赖和监听
NSOperationQueue * queue = [[NSOperationQueue alloc]init];
NSBlockOperation * op1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"download1 -- %@",[NSThread currentThread]);
}];
NSBlockOperation * op2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"download2 -- %@",[NSThread currentThread]);
}];
NSBlockOperation * op3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"download3 -- %@",[NSThread currentThread]);
}];
NSBlockOperation * op4 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"download4 -- %@",[NSThread currentThread]);
}];
op4.completionBlock = ^{
NSLog(@"download4 执行完毕-- %@",[NSThread currentThread]);
};
//设置依赖(可以保证线程执行的顺序)
[op3 addDependency:op1];//op3在op1之后执行
[op3 addDependency:op2];//op3在op2之后执行
// [op1 addDependency:op3];//不可以循环依赖
[queue addOperation:op1];
[queue addOperation:op2];
[queue addOperation:op3];
线程之间的通讯
NSOperationQueue * queue = [[NSOperationQueue alloc]init];
[queue addOperationWithBlock:^{
NSURL * url = [NSURL URLWithString:@"http://h.hiphotos.baidu.com/image/h%3D200/sign=ea111e09952397ddc9799f046983b216/dc54564e9258d1093cf78e5cd558ccbf6d814dc3.jpg"];
NSData * data = [NSData dataWithContentsOfURL:url];
UIImage * image = [UIImage imageWithData:data];
//回到主线程 刷新UI
[[NSOperationQueue mainQueue]addOperationWithBlock:^{
self.imageView.image = image;
}];
}];
###下载两张图片
NSOperationQueue * queue = [[NSOperationQueue alloc]init];
//下载图片1
__block UIImage * image1 = nil;
NSBlockOperation * download1 = [NSBlockOperation blockOperationWithBlock:^{
NSURL * url = [NSURL URLWithString:@"http://e.hiphotos.baidu.com/image/pic/item/8cb1cb1349540923592e4e479758d109b3de4947.jpg"];
NSData * data = [NSData dataWithContentsOfURL:url];
image1 = [UIImage imageWithData:data];
}];
//下载图片2
__block UIImage * image2 = nil;
NSBlockOperation * download2 = [NSBlockOperation blockOperationWithBlock:^{
NSURL * url = [NSURL URLWithString:@"http://a.hiphotos.baidu.com/image/pic/item/f9dcd100baa1cd11daf25f19bc12c8fcc3ce2d46.jpg"];
NSData * data = [NSData dataWithContentsOfURL:url];
image2 = [UIImage imageWithData:data];
}];
//合成图片
NSBlockOperation * combine = [NSBlockOperation blockOperationWithBlock:^{
UIGraphicsBeginImageContext(CGSizeMake(350, 400));
//绘制图片
[image1 drawInRect:CGRectMake(0, 0, 175, 400)];
image1 = nil;
[image2 drawInRect:CGRectMake(175, 0, 175, 400)];
image2 = nil;
UIImage * image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//回到主线程
[[NSOperationQueue mainQueue]addOperationWithBlock:^{
self.imageView.image = image;
}];
}];
//设置依赖
[combine addDependency:download1];
[combine addDependency:download2];
[queue addOperation:download1];
[queue addOperation:download2];
[queue addOperation:combine];
网友评论