前面了iOS的NSThread方法来实现多线程,这篇就简单的讲讲NSOperation和NSOperationQueue。

NSOperation是一个抽象类,定义一个要执行的任务。NSOperationQueue是一个任务队列,帮助对NSOperation所定义的任务进行管理。当任务加入到任务队列后,会自动按照优先级和依赖关系自动运行。

NSOperation是不能直接使用的,我们必须使用继承类。iOS提供了两个实现好的子类,分别是NSInvocationOperation和NSBlockOperation。NSOperation有个start方法,给你提供了一种不加入NSOperationQueue而运行任务的方式,当然这对于开发者来说要求更高一点。

我还是用上一篇的那个功能做例子,上代码:

- (void)viewDidLoad
{
[super viewDidLoad]; NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadImage:) object:IMAGE_URL];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:operation];
}

看上去很简单,仅仅就是创建任务,然后加入到队列。这个队列是个任务的pool,遵循生产者-消费者的关系,当有任务的时候会自动运行任务。我们可以使用setMaxConcurrentOperationCount:这个方法来设置这个queue里面的线程总数,默认值是-1,意思是没有限制。

在继承NSOperation后,对于非并发的工作,需要实现NSOperation子类的main方法:

-(void)main
{
@try
{
// 处理工作任务
}
@catch(...)
{
// 处理异常,但是不能再重新抛出异常
}
}

因为NSOperation的任务是可以cancel的,所以在main方法处理任务时就要不断轮询isCancelled。另外,这个main方法本来是空的,所以不需要调用[super main]这句。

还有一个start方法,这个start方法是工作的入口,通常是用来设置线程需要的运行环境的。和main一样,不要调用[super start]。这个方法还会区分这个运行的状态,如果是canceled或者已经结束了,这个任务就不会运行;而如果是正在运行或者还没ready,则会扔出一个异常。

如果要支持并发任务,至少需要重写start、isConcurrent、isExecuting、isFinished四个方法。这里需要说一下这个isConcurrent方法,这个方法是标志operation是否并行执行的,如果是concurrent的,则返回YES;反之,则返回NO。如果没有重写这个方法,则默认NO,但在OS X10.6之后,这个值被忽略了。

另外,NSOperation的一些属性是支持KVC的,我们可以通过KVO方法来观察这些属性并在应用的其他地方来控制程序运行,所以需要在合适的时候发出KVO通知。

NSOperation支持的KVO属性有:isCancelled、isConcurrent、isExecuting、isFinished、isReady、dependencies、queuePriority、completionBlock。如果你增加了属性,推荐同样支持KVC和KVO。

iOS多线程系列(2)的更多相关文章

  1. iOS多线程系列(3)

    在2011的WWDC上,苹果推出了GCD,从此多线程增加了一种新的方法.GCD要求运行在iOS4.0版本以上或者OS X10.6版本以上.GCD是Grand Central Dispatch的缩写,是 ...

  2. iOS多线程系列(1)

    多线程这个概念的接触是蛮早的时候了,当时还是单核单CPU的时候,Thread这个概念已经出现了,当时比较流行的方案是时间片轮流,线程可以优先级抢占,但一次只能运行一个线程,实际上多线程是不能真正并行处 ...

  3. iOS开发系列--数据存取

    概览 在iOS开发中数据存储的方式可以归纳为两类:一类是存储为文件,另一类是存储到数据库.例如前面IOS开发系列-Objective-C之Foundation框架的文章中提到归档.plist文件存储, ...

  4. iOS开发系列--网络开发

    概览 大部分应用程序都或多或少会牵扯到网络开发,例如说新浪微博.微信等,这些应用本身可能采用iOS开发,但是所有的数据支撑都是基于后台网络服务器的.如今,网络编程越来越普遍,孤立的应用通常是没有生命力 ...

  5. iOS开发系列--并行开发其实很容易

    --多线程开发 概览 大家都知道,在开发过程中应该尽可能减少用户等待时间,让程序尽可能快的完成运算.可是无论是哪种语言开发的程序最终往往转换成汇编语言进而解释成机器码来执行.但是机器码是按顺序执行的, ...

  6. 【转】iOS开发系列--数据存取

    原文: http://www.cnblogs.com/kenshincui/p/4077833.html#SQLite 概览 在iOS开发中数据存储的方式可以归纳为两类:一类是存储为文件,另一类是存储 ...

  7. iOS多线程开发之离不开的GCD(上篇)

    一.GCD基本概念 GCD 全称Grand Central Dispatch(大中枢队列调度),是一套低层API,提供了⼀种新的方法来进⾏并发程序编写.从基本功能上讲,GCD有点像NSOperatio ...

  8. iOS开发系列

    因为最近面试了一些人,校招.初中级.高级.架构师,各种级别的,发现大家水平差异很大,有的高级的工程师很多问题都回答不上来,所以想梳理下iOS的知识点,写成一个系列,如果时间允许的话,会录制成视频放到网 ...

  9. iOS 多线程:『RunLoop』详尽总结

    1. RunLoop 简介 1.1 什么是 RunLoop? 可以理解为字面意思:Run 表示运行,Loop 表示循环.结合在一起就是运行的循环的意思.哈哈,我更愿意翻译为『跑圈』.直观理解就像是不停 ...

随机推荐

  1. 重读LPTHW-Lesson37

    这次是复习课  复习python符号  整理如下 1.逻辑运算符not.and.or python中逻辑运算符包括not(布尔非).and(布尔与).or(布尔或).注意以下几点: ①运算规则: 例: ...

  2. 正式学习React (六) 项目篇

    https://github.com/huenchao/yingshili 或者点这里 注意事项看ReadME.md 会持续更新,反正就是把之前分析的redux react-redux都用一下,然后会 ...

  3. GDAL与OpenCV2.X数据转换(适合多光谱和高光谱等多通道的遥感影像)

    一.前言 GDAL具有强大的图像读写功能,但是对常用图像处理算法的集成较少,OpenCV恰恰具有较强的图像处理能力,因此有效的结合两者对图像(遥感影像)的处理带来了极大的方便.那么如何实现GDAL与o ...

  4. 一个简单的flask程序

    初始化 所有Flask程序都必须创建一个程序实例. 程序实例是Flask类的对象,经常使用下述代码创建: from flask import Flask app = Flask(__name__) F ...

  5. OC基础13:数字、字符串和集合2

    "OC基础"这个分类的文章是我在自学Stephen G.Kochan的<Objective-C程序设计第6版>过程中的笔记. 17.Foundation框架的数组是有序 ...

  6. 委托-异步调用-泛型委托-匿名方法-Lambda表达式-事件【转】

    1. 委托 From: http://www.cnblogs.com/daxnet/archive/2008/11/08/1687014.html 类是对象的抽象,而委托则可以看成是函数的抽象.一个委 ...

  7. 通过P-SMR看State Machine Replication

    在一个复制系统中,为了保持一致性,各个replicated server是串行运行.这样性能上就会比仅仅有一台server的系统慢,由于仅仅有一台server能够进行并行处理.假设在复制系统中各个se ...

  8. oracle子查询

    子查询:在一个查询的内部包含另外一个查询. 普通子查询 -- 查询出比7654工资还高的所有雇员的信息 select * from emp e where e.sal > (select sal ...

  9. ORACLE 热备begin backup / end backup

    执行begin backup之后,oracle会把将要备份的数据文件都标记为hot-backup-in-progress,锁定所要备份的datafile header的scn,例如此时scn=100, ...

  10. JavaScript 回车 焦点切换(摘抄)

    <!-- 这是回车转换行的代码段--> <script language='javascript' for='document' event='onkeydown'> if(e ...