1. 含义:NSOperation,NSOperationQueue是什么。

The NSOperation class is an abstract class you use to encapsulate the code and data associated with a single task.NSOperation是一个你需要将代码和数据放在一个单任务中执行的抽象类。

The NSOperationQueue class regulates the execution of a set of NSOperation objects.NSOperationQueue是用来管理多个NSOperation对象的一个类。

2.使用方法

使用 NSOperation的方式有两种,

  1. 一种是用定义好的两个子类:

NSInvocationOperation 和 NSBlockOperation。

@interface ViewController ()  

@end  

@implementation ViewController  

- (void)viewDidLoad
{
[super viewDidLoad];
NSInvocationOperation *operation = [[NSInvocationOperation alloc]initWithTarget:self
selector:@selector(downloadImage:)
object:kURL]; NSOperationQueue *queue = [[NSOperationQueue alloc]init];
[queue addOperation:operation];
// Do any additional setup after loading the view, typically from a nib.
} -(void)downloadImage:(NSString *)url{
NSLog(@"url:%@", url);
NSURL *nsUrl = [NSURL URLWithString:url];
NSData *data = [[NSData alloc]initWithContentsOfURL:nsUrl];
UIImage * image = [[UIImage alloc]initWithData:data];
[self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];
}
-(void)updateUI:(UIImage*) image{
self.imageView.image = image;
}

2.另一种则是继承NSOperation,重写NSOperation的main方法

编写一个NSOperation的子类,只需实现main方法。这里非常类似Java的Thread,你可以继承它,并覆盖run方法,在该方法里面写入需要执行的代码。这里的main方法和run方法作用是相似的。

@interface MyTask : NSOperation {
int operationId;
} @property int operationId; @end

这里的operationId属性不是必须的,是我想在后面标识区分多个Task的标识位。

@implementation MyTask

@synthesize operationId;

- (void)main{
NSLog(@"task %i run … ",operationId);
[NSThread sleepForTimeInterval:];
NSLog(@"task %i is finished. ",operationId);
} @end

这里模拟了一个耗时10秒钟的操作。

-- ::14.622 MultiThreadTest[:] task  run …
-- ::24.623 MultiThreadTest[:] task is finished.

可以向操作队列(NSOperationQueue)增加多个操作,比如这样:

下面需要把Task加入到队列中:

- (void)viewDidLoad {
[super viewDidLoad];
queue=[[NSOperationQueue alloc] init]; int index=;
MyTask *task=[[[MyTask alloc] init] autorelease];
task.operationId=index++; [queue addOperation:task];

我直接找了个Controller的方法写上了。运行结果是,界面出现了,而task还未执行完,说明是多线程的。10秒钟后,日志打印完毕,类似这样:

- (void)viewDidLoad {
[super viewDidLoad];
queue=[[NSOperationQueue alloc] init]; int index=;
MyTask *task=[[[MyTask alloc] init] autorelease];
task.operationId=index++;
[queue addOperation:task]; task=[[[MyTask alloc] init] autorelease];
task.operationId=index++; [queue addOperation:task];
}

那么打印出的内容是不定的,有可能是这样:

-- ::48.087 MultiThreadTest[:] task  run …
-- ::48.087 MultiThreadTest[:] task run …
-- ::58.122 MultiThreadTest[:] task is finished.
-- ::58.122 MultiThreadTest[:] task is finished.

甚至有可能是这样:

-- ::24.686 MultiThreadTest[:1b03] task  run …
-- ::24.685 MultiThreadTest[:] task run …
-- ::34.708 MultiThreadTest[:1b03] task is finished.
-- ::34.708 MultiThreadTest[:] task is finished.

因为两个操作提交的时间间隔很近,线程池中的线程,谁先启动是不定的。

那么,如果需要严格意义的顺序执行,怎么办呢?

处理操作之间的依赖关系

如果操作直接有依赖关系,比如第二个操作必须等第一个操作结束后再执行,需要这样写:

queue=[[NSOperationQueue alloc] init];

int index=;
MyTask *task=[[[MyTask alloc] init] autorelease];
task.operationId=index++; [queue addOperation:task]; task=[[[MyTask alloc] init] autorelease];
task.operationId=index++; if ([[queue operations] count]>) {
MyTask *theBeforeTask=[[queue operations] lastObject];
[task addDependency:theBeforeTask];
} [queue addOperation:task];

这样,即使是多线程情况下,可以看到操作是严格按照先后次序执行的。

控制线程池中的线程数

可以通过类似下面的代码:

[queue setMaxConcurrentOperationCount:];

来设置线程池中的线程数,也就是并发操作数。默认情况下是-1,也就是没有限制,同时运行队列中的全部操作。

IOS多线程(NSOperation,NSOperationQueue)的更多相关文章

  1. iOS 多线程 NSOperation、NSOperationQueue

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

  2. iOS多线程 NSOperation的用法

    上一篇写了 GCD 的使用,接下来就了解一下 NSOperation ,NSOperation是苹果对 GCD 的 OC 版的一个封装,但是相对于GCD来说可控性更强,并且可以加入操作依赖. NSOp ...

  3. iOS多线程--NSOperation 浅显易懂

    NSOperation是基于GCD的一套多线程实现方案,和GCD一样,线程的生命周期是由系统来自动管理的,不用像NSThread和Pthread一样让程序员手动管理.相对于GCD来说,它更加地面向对象 ...

  4. iOS多线程--NSOperation

    NSOperation是基于GCD的一套多线程实现方案,和GCD一样,线程的生命周期是由系统来自动管理的,不用像NSThread和Pthread一样让程序员手动管理.相对于GCD来说,它更加地面向对象 ...

  5. iOS多线程---NSOperation介绍和使用

    1.  NSOperation实现多线程编程,需要和NSOperationQueue一起使用. (1)先将要执行的操作封装到NSOperation中 (2)将NSOperation对象添加到NSOpe ...

  6. IOS 多线程 NSOperation GCD

    1.NSInvocationOperation NSInvocationOperation * op; NSOperationQueue * que = [[NSOperationQueuealloc ...

  7. iOS多线程---NSOperation的常用操作

    1.最大并发数: - (NSInteger)maxConcurrentOperationCount;- (void)setMaxConcurrentOperationCount:(NSInteger) ...

  8. iOS多线程编程

    废话不多说,直接上干货.先熟悉一下基本知识,然后讲一下常用的两种,NSOperation和GCD. 一.基础概念 进程: 狭义定义:进程是正在运行的程序的实例(an instance of a com ...

  9. [转] iOS多线程编程之NSOperation和NSOperationQueue的使用

    <iOS多线程编程之NSThread的使用> 介绍三种多线程编程和NSThread的使用,这篇介绍NSOperation的使用. 使用 NSOperation的方式有两种, 一种是用定义好 ...

  10. iOS多线程编程之NSOperation和NSOperationQueue的使用

    前一篇 <iOS多线程编程之NSThread的使用> 介绍三种多线程编程和NSThread的使用,这篇介绍NSOperation的使用. 使用 NSOperation的方式有两种, 一种是 ...

随机推荐

  1. Windows Server 2008 显示桌面图标

    相信有朋友们有安装使用过windows 2008 server服务器,刚安装好的时候,桌面上只有一个回收站的图标,它没有像windows 7或windows 8一样可以直接通过右击鼠标的菜单来设置,要 ...

  2. Vijos1056 图形面积

    描述 桌面上放了N个平行于坐标轴的矩形,这N个矩形可能有互相覆盖的部分,求它们组成的图形的面积. 格式 输入格式 输入第一行为一个数N(1≤N≤100),表示矩形的数量.下面N行,每行四个整数,分别表 ...

  3. PHP中soap的使用例子

    PHP 使用soap有两种方式. 一.用wsdl文件 服务器端. <?phpclass service{ public function HelloWorld() { return " ...

  4. map 几种遍历方法

    public static void main(String[] args) { Map<String, String> map = new HashMap<String, Stri ...

  5. Ognl基本使用

    ---恢复内容开始--- Ognl默认是从“根”中取数据的 下面Demo中用的是 Ognl.getValue(String expression, Map context, Object root) ...

  6. html5视频播放器

    <!doctype html> <html> <head> <meta http-equiv="Content-Type" content ...

  7. juery动态添加和删除

    拼语句添加框(不能删除原有的tr) //点击a标签 $("#a").on("click",function(){ var $newtr = $("&l ...

  8. gcc的-D和-U参数:宏的设置与取消 _CCFLAGS=" -w -enable-threads=posix -DLINUX -D_REENTRANT -DWORKONGN -Dlinux -D_GN_DETAIL_SDR_"

    _CCFLAGS=" -w -enable-threads=posix -DLINUX -D_REENTRANT -DWORKONGN -Dlinux -D_GN_DETAIL_SDR_&q ...

  9. mysql链接数据库时报错

    今天在命令行下链接mysql数据库报错,如下: ERROR (HY000): Can't connect to MySQL server on 'ost' (113) 这是一个什么玩意呢,怎么会报这个 ...

  10. 大数据下Limit使用(MySQL)

    对于一直用Oracle的我,今天可是非常诧异,MySQL中同一个函数在不同数量级上的性能居然差距如此之大. 先看表ibmng(id,title,info)  唯一  id key 索引title 先看 ...