使用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实现多线程的更多相关文章

  1. 用NSOperation和NSOperationQueue实现多线程编程

    1.上一讲简单介绍了NSThread的使用,虽然也可以实现多线程编程,但是需要我们去管理线程的生命周期,还要考虑线程同步.加锁问题,造成一些性能上的开销.我们也可以配合使用NSOperation和NS ...

  2. iOS开发——多线程篇——NSOperation(基于GCD多线程编程),下载图片并合成新图片

    一.NSOperation的基本概念1.简介NSOperation的作用配合使用NSOperation和NSOperationQueue也能实现多线程编程 NSOperation和NSOperatio ...

  3. iOS 之NSOperation(一)

    一.NSOperation的介绍 1.NSOperation的作用 配合使用NSOperation和NSOperationQueue实现多线程编程 2.实现多线程的具体步骤 1)将需要执行的操作封装到 ...

  4. NSOperation、NSOperationQueue

    NSOperation.NSOperationQueue NSOperation 和 NSOperationQueue 配合使用也能实现多线程. NSOperation 继承于 NSObject,是一 ...

  5. iOS 多线程 NSOperation、NSOperationQueue

    1. NSOperation.NSOperationQueue 简介 NSOperation.NSOperationQueue 是苹果提供给我们的一套多线程解决方案.实际上 NSOperation.N ...

  6. iOS GCD NSOperation NSThread等多线程各种举例详解(拷贝)

    2年多的iOS之路匆匆而过,期间也拜读来不少大神的博客,近来突然为自己一直做伸手党感到羞耻,是时候回馈社会.回想当年自己还是小白的时候,照着一些iOS多线程教程学,也只是照抄,只知其然.不知其所以然. ...

  7. iOS GCD NSOperation NSThread等多线程各种举例详解

    废话就不多说,直接上干货.如下图列举了很多多线程的知识点,每个按钮都写有对应的详细例子,并对运行结果进行分析,绝对拿实践结果来说话.如果各位道友发现错误之处还请指正.附上demo下载地址

  8. 多线程下的NSOperation和NSOperationQueue的使用

    多线程下的NSOperation和NSOperationQueue的使用 NSOperation和NSOperationQueue的介绍: NSOperation是Cocoa中的一个抽象类,用来封装单 ...

  9. Swift - 多线程实现方式(2) - NSOperation和NSOperationQueue

    1,Swift继续使用Object-C原有的一套线程,包括三种多线程编程技术: (1)NSThread (2)Cocoa NSOperation(NSOperation和NSOperationQueu ...

随机推荐

  1. Jmeter 中多线程并发和循环控制器

    今天遇到一个场景, 给一个手机号发送短信验证码,通过正确输入短信验证码即登录并获得token,进行其他操作. 短信验证码是4位,即9999个组合, 接口没有对验证次数做校验,所以可以一直一直尝试通过验 ...

  2. 《剑指offer》第七题(重要!重建二叉树)

    文件一:main.cpp // 面试题:重建二叉树 // 题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输 // 入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历 ...

  3. dockfile杂项

    工程源代码+工程的配置文件 在外面配置好 1 工程的配置文件,是工程的一部分 2 要贯彻内聚原则, 用1句挂载整个工程. 在外面集中配置好在一个路径下,一起挂进去或者COPY进去. 防止先COPY了体 ...

  4. js中如何访问对象和数组

    js中如何访问对象和数组 一.总结 一句话总结:js访问对象点和中括号,访问数组的话就是中括号 对象 . [] 数组 [] 1.js访问对象的两种方式? . [] 可以使用下面两种方式访问对象的属性和 ...

  5. Java知识集锦

    Java知识集锦 一.Java程序基础 1.1 开发和运行环境 1.2 Java语言概述 二.Java语法基础 2.1 基础类型和语法 2.2 对象和类型 2.3 包和访问控制 三.数据类型及类型转换 ...

  6. 各个安卓版本 使用的 Linux Kernel Version

    Android Version |API Level |Linux Kernel in AOSP --------------------------------------------------- ...

  7. hdu2110(多重背包/母函数)

    http://acm.hdu.edu.cn/showproblem.php?pid=2110 就是个多重背包,有坑点-.-.注意答案模10000中间结果有可能会爆所以计算时就要取模: 由于必须能均分三 ...

  8. char,varchar与text类型的区别和选用

    (1)char: 它是定长格式的,但是长度范围是0~255. 当你想要储存一个长度不足255的字符时,mysql会用空格来填充剩下的字符.因此在读取数据时,char类型的数据要进行处理,把后面的空格去 ...

  9. div在IE6中固定

    在IE6中固定一div在右下角,但是ie6不支持position:fixed属性,那么只能通过js实现,通过js判断浏览器在ie6的情况下,div的position为absoluate:right:0 ...

  10. bzoj1091

    题解: 暴力枚举顺序 然后计算几何 代码: #include<bits/stdc++.h> ],lp=; double v1,v2,ans=1e10; struct pos { doubl ...