IOS多线程(NSOperation,NSOperationQueue)
- 含义: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的方式有两种,
一种是用定义好的两个子类:
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)的更多相关文章
- iOS 多线程 NSOperation、NSOperationQueue
1. NSOperation.NSOperationQueue 简介 NSOperation.NSOperationQueue 是苹果提供给我们的一套多线程解决方案.实际上 NSOperation.N ...
- iOS多线程 NSOperation的用法
上一篇写了 GCD 的使用,接下来就了解一下 NSOperation ,NSOperation是苹果对 GCD 的 OC 版的一个封装,但是相对于GCD来说可控性更强,并且可以加入操作依赖. NSOp ...
- iOS多线程--NSOperation 浅显易懂
NSOperation是基于GCD的一套多线程实现方案,和GCD一样,线程的生命周期是由系统来自动管理的,不用像NSThread和Pthread一样让程序员手动管理.相对于GCD来说,它更加地面向对象 ...
- iOS多线程--NSOperation
NSOperation是基于GCD的一套多线程实现方案,和GCD一样,线程的生命周期是由系统来自动管理的,不用像NSThread和Pthread一样让程序员手动管理.相对于GCD来说,它更加地面向对象 ...
- iOS多线程---NSOperation介绍和使用
1. NSOperation实现多线程编程,需要和NSOperationQueue一起使用. (1)先将要执行的操作封装到NSOperation中 (2)将NSOperation对象添加到NSOpe ...
- IOS 多线程 NSOperation GCD
1.NSInvocationOperation NSInvocationOperation * op; NSOperationQueue * que = [[NSOperationQueuealloc ...
- iOS多线程---NSOperation的常用操作
1.最大并发数: - (NSInteger)maxConcurrentOperationCount;- (void)setMaxConcurrentOperationCount:(NSInteger) ...
- iOS多线程编程
废话不多说,直接上干货.先熟悉一下基本知识,然后讲一下常用的两种,NSOperation和GCD. 一.基础概念 进程: 狭义定义:进程是正在运行的程序的实例(an instance of a com ...
- [转] iOS多线程编程之NSOperation和NSOperationQueue的使用
<iOS多线程编程之NSThread的使用> 介绍三种多线程编程和NSThread的使用,这篇介绍NSOperation的使用. 使用 NSOperation的方式有两种, 一种是用定义好 ...
- iOS多线程编程之NSOperation和NSOperationQueue的使用
前一篇 <iOS多线程编程之NSThread的使用> 介绍三种多线程编程和NSThread的使用,这篇介绍NSOperation的使用. 使用 NSOperation的方式有两种, 一种是 ...
随机推荐
- 【POJ 2886】Who Gets the Most Candies?
题意 约瑟夫问题的升级版,每次出去的是前一个出去的人位置+手上的数字(正往前,负往后).第i个出去的人拿的糖是i的约数的个数.求拿糖最多的人和他的糖果数. 分析 线段树单点更新,反素数. 我竟然WA在 ...
- Python 之我见
读音 Python(KK 英语发音:/ˈpaɪθən/) 序言 其实早前就已经接触了python这个功能强大的脚本语言,但是那时只是基于兴趣而学习,目的性并不是很强,所以学习的并不是很深入.最近由于闲 ...
- Erlang之父的学习历史及学习建议
当我开始学习编程的时候(1967年),我可以在 FORTRAN 和(传说中的)Algol 之间选择,不过没有任何人了解 Algol,所以我选择了 FORTRAN. 在我最早学习编程的时候,我的编程周期 ...
- Opencv加载和显示图片
#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <ios ...
- std::bind(二)
bind - boost 头文件: boost/bind.hpp bind 是一组重载的函数模板. 用来向一个函数(或函数对象)绑定某些参数. bind的返回值是一个函数对象. 它的源文件太长了. 看 ...
- 锋利的jQuery-2--判断jQuery获取到的对象是否存在$().length
1.使用js获取不存在的对象: document.getElementById("tt").style.color = "red"; 如果网页中不存在id = ...
- Lex和Yacc入门
Lex和Yacc入门 标签: lexyacc 2013-07-21 23:02 584人阅读 评论(0) 收藏 举报 分类: Linux(132) 原文地址:http://coanor.blog ...
- java类的加载过程
1.类的加载顺序 (1)JVM在首次加载类时会对 静态初始化块.静态成员变量. 静态方法进行一次初始化. (2)只有在调用new方法时才会创建类的实例. (3)对象创建过程: 首先执行父类(如果有) ...
- error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项:值“0”不匹配值“2”
error: vtkCommon.lib(vtkSmartPointerBase.obj) : error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项:值“0”不 ...
- 粒子滤波particle filter和目标跟踪
粒子滤波用于跟踪,参考:http://www.cnblogs.com/tornadomeet/archive/2012/03/18/2404817.html http://blog.csdn.net/ ...