iOS-----使用NSOperation与NSOperationQueue实现多线程
使用NSOperation与NSOperationQueue实现多线程
NSOperation与NSOperationQueue的基本理论如下。
|
NSOperationQueue |
代表一个FIFO的队列,它负责管理系统提交的多个NSOperation,NSOperationQueue底层维护一个线程池,会按顺序启动线程来执行提交给该队列的NSOperation任务 |
|
|
NSOperation |
代表一个多线程任务。NSOperation还有NSInvocationOperation、NSBlockOperation两个子类。NSOperation有两种使用方式:①开发者实现NSOperation的子类;②开发者直接使用NSInvocationOperation或NSBlockOperation子类。 |
|
|
使用NSOperation、NSOperationQueue开发多线程非常简单,只要如下两步 |
||
|
1 |
创建NSOperationQueue队列,并为该队列设置相关属性。 |
|
|
2 |
创建NSOperation子类的对象,并将该对象提交给NSOperationQueue队列,该队列将会按顺序依次启用每个NSOperation。 |
|
|
NSOperationQueue负责管理、执行所有的NSOperation,它底层维护着一个线程池,开发者提交的NSOperation正是由该线程池中的线程负责执行的。NSOperationQueue提供了如下常用方法。 |
||
![]() |
||
![]() |
||
使用NSInvocationOperation和NSBlockOperation
NSInvocationOperation和NSBlockOperation都是NSOperation的子类,都可在程序中直接使用,用于封装需要异步执行的任务。
NSInvocationOperation和NSBlockOperation在用法上非常相似,区别是NSInvocationOperation用于将特定对象的特定方法封装成NSOperation,而NSBlockOperation则用于将代码封装成NSOperation。
创建NSInvocationOperation的代码片段如下:

创建NSBlockOperation的代码片段如下:

一旦得到NSOperation对象之后,将NSOperation对象提交给NSOperationQueue即可。
实例:使用NSBlockOperation下载图片
下面是该实例的视图控制器类的实现部分代码。
@implementation ViewController
NSOperationQueue* queue;
- (void)viewDidLoad
{
[super viewDidLoad];
queue = [[NSOperationQueue alloc] init];
// 设置该队列最大支持10个并发线程
queue.maxConcurrentOperationCount = ;
}
- (IBAction)clicked:(id)sender
{
NSString* url = @” http://pic14.nipic.com/20110522/7411759_164157418126_2.jpg”;
// 以传入的代码块作为执行体,创建NSOperation
NSBlockOperation* operation = [NSBlockOperation blockOperationWithBlock:^{
// 从网络获取数据
NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:url]];
// 将网络数据初始化为UIImage对象
UIImage *image = [[UIImage alloc] initWithData: data];
if(image != nil)
{
// 在主线程中执行updateUI:方法
[self performSelectorOnMainThread:@selector(updateUI:)
withObject:image waithUntilDone:YES];// ①
}
else
{
NSLog(@”---下载图片出现错误---”);
}
}];
// 将NSOperation添加给NSOperationQueue
[queue addOperation:operation];
}
- (void)updateUI:(UIImage*)image
{
self.iv.image = image;
}
@end
该程序创建了一个NSBlockOperation对象,接下来将该对象提交给NSOperationQueue即可.由于该代码块将会在线程中执行,因此程序在①号代码处调用了performSelectorOnMainThread:withObject: waitUntilDone:方法在主线程中更新iv控件显示的图片.
定义NSOperation子类
NSOperation一般不会直接拿来使用,而是选择创建它的子类,创建NSOperation的子类需要重写一个方法:- (void)main,该方法的方法将作为NSOperationQueue完成的任务。
下面程序示范了使用NSOperation的子类来下载网络图片。该示例的界面与前面介绍的使用NSThread下载图片的界面基本相似,只是该程序将会使用NSOperation的子类来启动多线程执行下载。该示例的界面上同样只有一个UIImageView和一个UIButton,程序为UIButton的“Touch Up Inside”时间绑定clicked:事件处理方法。
下面是LCDownImageOperation类的接口部分代码。
|
代 码 片 段 |
LCDownLoadImageOperation.h文件
#import<Foundation/Foundation.h>
// 定义NSOperation的子类
@interface LCDownImageOperation:NSOperation
@property (nonatomic, strong)NSURL* url;
@property (nonatomic, weak)UIImageView* imageView;
- (id)initWithURL:(NSURL*)url imageView:(UIImageView*)iv;
@end
LCDownLoadImageOperation.m文件
@implementation LCDownLoadImageOperation
- (id)initWithURL:(NSURL*)url imageView:(UIImageView*)iv
{
self = [super init];
if(self)
{
_imageView = iv;
_url = url;
}
return self;
}
// 重写main方法,该方法将作为线程执行体
- (void)main
{
// 从网络获取数据
NSData *data = [[NSData alloc] initWithContentsOfURL:self.url];
// 将网络数据初始化为UIImage对象
UIImage *image = [[UIImage alloc] initWithData;data];
if(image !=nil)
{
// 在主线程中执行updateUI:方法
[self performSelectorOnMainThread:@selector(updateUI:)
withObject:image waitUntilDone:YES];// ①
}
else
{
NSLog(@”+++下载图片出现错误+++”);
}
}
- (void)updateUI:(UIImage*)image
{
self.imageView.image = image;
}
@end
|
|
说明 |
上面的代码创建了NSOperation类的子类,并重写了main方法,该方法将会作为该NSOperation所启动线程的执行体----也就是代表该线程要完成的任务.由于main方法的代码将会在新线程中执行,因此程序同样调用了performSelectorOnMainThread:withObject:waitUntilDone:方法在主线程中更新iv控件显示的图片. |
|
代码片段 |
创建了该NSOperation的子类之后,接下来只要创建该子类的实例,并将它提交给NSOperationQueue即可.视图控制器类的实现部分使用了LCDownImageOperation从网络下载图片.下面是视图控制器类的实现部分代码. ViewController.m
@implementation ViewController
NSOperationQueue *queue;
- (void)viewDidLoad
{
[super viewDidLoad];
queue = [[NSOperationQueue alloc] init];
// 设置该队列最大支持10个并发线程
queue.maxConcurrentOperationCount = ;
}
- (IBAction)clicked:(id)sender
{
// 定义要加载的图片的URL
NSURL *url = [NSURL URLWithString:@” http://img2.imgtn.bdimg.com/it/u=194240101,2532182839&fm=21&gp=0.j pg”];
// 创建LCDownImageOperation对象
LCDownImageOperation* operation = [[LCDownImageOperation alloc] initWithURL:url imageView:self.iv];
// 将NSOperation的子类的实例提交给NSOperationQueue
[queue addOperation:operation];
}
@end
|
|
说明 |
上面程序中的代码就是使用LCDownImageOperation实现多线程下载的关键代码,只要创建LCDownImageOperation实例,然后将该实例提交给NSOperationQueue即可. |
|
小结 |
iOS提供了3种多线程支持:①使用NSThread开发多线程应用;②使用GCD实现多线程;③使用NSOperation和NSOperationQueue实现多线程. |
iOS-----使用NSOperation与NSOperationQueue实现多线程的更多相关文章
- 用NSOperation和NSOperationQueue实现多线程编程
1.上一讲简单介绍了NSThread的使用,虽然也可以实现多线程编程,但是需要我们去管理线程的生命周期,还要考虑线程同步.加锁问题,造成一些性能上的开销.我们也可以配合使用NSOperation和NS ...
- iOS开发——多线程篇——NSOperation(基于GCD多线程编程),下载图片并合成新图片
一.NSOperation的基本概念1.简介NSOperation的作用配合使用NSOperation和NSOperationQueue也能实现多线程编程 NSOperation和NSOperatio ...
- iOS 之NSOperation(一)
一.NSOperation的介绍 1.NSOperation的作用 配合使用NSOperation和NSOperationQueue实现多线程编程 2.实现多线程的具体步骤 1)将需要执行的操作封装到 ...
- NSOperation、NSOperationQueue
NSOperation.NSOperationQueue NSOperation 和 NSOperationQueue 配合使用也能实现多线程. NSOperation 继承于 NSObject,是一 ...
- iOS 多线程 NSOperation、NSOperationQueue
1. NSOperation.NSOperationQueue 简介 NSOperation.NSOperationQueue 是苹果提供给我们的一套多线程解决方案.实际上 NSOperation.N ...
- iOS GCD NSOperation NSThread等多线程各种举例详解(拷贝)
2年多的iOS之路匆匆而过,期间也拜读来不少大神的博客,近来突然为自己一直做伸手党感到羞耻,是时候回馈社会.回想当年自己还是小白的时候,照着一些iOS多线程教程学,也只是照抄,只知其然.不知其所以然. ...
- iOS GCD NSOperation NSThread等多线程各种举例详解
废话就不多说,直接上干货.如下图列举了很多多线程的知识点,每个按钮都写有对应的详细例子,并对运行结果进行分析,绝对拿实践结果来说话.如果各位道友发现错误之处还请指正.附上demo下载地址
- 多线程下的NSOperation和NSOperationQueue的使用
多线程下的NSOperation和NSOperationQueue的使用 NSOperation和NSOperationQueue的介绍: NSOperation是Cocoa中的一个抽象类,用来封装单 ...
- Swift - 多线程实现方式(2) - NSOperation和NSOperationQueue
1,Swift继续使用Object-C原有的一套线程,包括三种多线程编程技术: (1)NSThread (2)Cocoa NSOperation(NSOperation和NSOperationQueu ...
随机推荐
- 《WAP团队》项目系统设计改进与详细设计
任务1: 一.分析<基于家教管理系统项目需求规格说明书>初稿的不足,特别是文档需求描述建模不完整的内容. 通过软件工程更深入的学习发现我们的需求分析建模明显不足,缺少最重要的类图. 二.团 ...
- marquee 跑马灯公告
1.原始 marquee 2.自定义 marquee .tops { color: #fff; height: 23px; margin: 0 0 0 20px; min-height: 23px; ...
- Unity中使用的一套敏感词过滤方式
当项目中的敏感词数量不是很多的时候,直接用数组来遍历过滤其实也可以,但是具体的数量有多大,这个肯定不好说,因此,对.txt中的敏感词合理组织后再进行过滤就显得非常有必要了. 如上图,左边是txt中配置 ...
- NHibernate 映射关系
基本映射关系如下: NHibernate类型 .NET类型 Database类型 备注 AnsiChar System.Char DbType.AnsiStringFixedLength - 1 ch ...
- docker on mac:误删default vm的处理方法
通过docker-machine 重新建一个vm,在virtualbox里可以直接看到多出来一个vm docker-machine create --driver virtualbox default
- English trip V1 - 3.What Would you Like? Teacher:Lamb Key: would like to
In this lesson you will learn to talk about fast food and health. would = will 的过去式 STARTER 1.Tell y ...
- English trip -- VC(情景课) 8 A Get ready
Words cashier # 收银员 a cashier counts money 收钱 custodian # 清洁工 a custodian cl ...
- President's Path CodeForces - 416E (最短路,计数)
大意: 给定无向图, 求任意两点间所有最短路经过的边数 刚开始想先用floyd跑出最短路, 然后在DAG上DP, 交了1发, 发现会算重复 贴一下题解的做法 #include <iostream ...
- ubuntu mysql主从库的搭建
1,首先我们要确定一个从库一个主库,紧记从库只能读取不能有其他的操作,如果操作写那主从就失效了,那就看看我们这么搭建主从吧! 2. 环境:Ubuntu,Mysql (主从的数据库版本必须保持一致) 主 ...
- SMTP 发邮件
public class EmailOrderProcessor :IOrderProcessor { private EmailSettings es; public EmailOrderProce ...

