本文主要对NSOPeration的一些重点属性和方法做出介绍,以便大家可以更好的使用NSOPeration。

1.添加依赖

- (void)addDependency:(NSOperation *)op;

  需求:同时下载两张图片,两张图片都下载完了,在合成成一张。这个例子我在iOS多线程之6.GCD的其他用法这篇文章中用过,当时是用GCD的group实现的。这次我们用NSOPeration实现。

代码

// 点击屏幕下载图片
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { __block UIImage *image1 = nil;
// 下载图片1
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"下载第一张图片%@",[NSThread currentThread]);
NSString *strURL1 = @"http://h.hiphotos.baidu.com/zhidao/pic/item/6d81800a19d8bc3ed69473cb848ba61ea8d34516.jpg";
image1 = [self downloadImageWithURL:strURL1];
}];
__block UIImage *image2 = nil;
// 下载图片2
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"下载第二张图片%@",[NSThread currentThread]);
NSString *strURL2 = @"http://h.hiphotos.baidu.com/zhidao/pic/item/0eb30f2442a7d9334f268ca9a84bd11372f00159.jpg";
image2 = [self downloadImageWithURL:strURL2];
}]; // 两张图片下载完 再合并图片
NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"合并图片%@",[NSThread currentThread]);
// 在主线程刷新UI
dispatch_async(dispatch_get_main_queue(), ^{
self.imageView1.image = image1;
self.imageView2.image = image2;
// 合并两张图片图片
UIGraphicsBeginImageContextWithOptions(CGSizeMake(200, 100), NO, 0.0);
[image1 drawInRect:CGRectMake(0, 0, 100, 100)];
[image2 drawInRect:CGRectMake(100, 0, 100, 100)];
self.imageView3.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext(); });
}]; // 添加依赖
[operation3 addDependency:operation1];
[operation3 addDependency:operation2]; // 创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// 把操作放队列中
[queue addOperation:operation1];
[queue addOperation:operation2];
[queue addOperation:operation3];
} - (UIImage *)downloadImageWithURL : (NSString *)strURL {
NSURL *url = [NSURL URLWithString:strURL];
return [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];
}

日志

2016-11-12 09:23:42.013 TTTTTTTTTT[2544:33281] 下载第二张图片<NSThread: 0x60000007ec40>{number = 4, name = (null)}
2016-11-12 09:23:42.013 TTTTTTTTTT[2544:33282] 下载第一张图片<NSThread: 0x60000007cac0>{number = 3, name = (null)}
2016-11-12 09:23:42.141 TTTTTTTTTT[2544:33309] 合并图片<NSThread: 0x60800007e700>{number = 6, name = (null)}

效果:



分析 :只有两张图片下载完,合并图片才有意义,所以operation3里面的操作必须等operation1和operation2里操作完成才能执行。

[operation3 addDependency:operation1];

operation3依赖于operation1,就是operation3等operation1执行完再执行。

注意:依赖一定在把operation添加进queue之前添加,否则就没有意义了。

  既有添加依赖,就有移除依赖。

- (void)removeDependency:(NSOperation *)op;

2.设置operation的优先级

@property NSOperationQueuePriority queuePriority;

   当把操作(operation)放入队列(queue)中的时候,是遵守先进先出原则。但是如果你设置了操作(operation)的优先级,那么优先级高的就可以先执行。NSOperationQueuePriority 是一个枚举,共有五个值。

typedef NS_ENUM(NSInteger, NSOperationQueuePriority) {
NSOperationQueuePriorityVeryLow = -8L,// 优先级很低
NSOperationQueuePriorityLow = -4L,// 优先级低
NSOperationQueuePriorityNormal = 0,// 优先级正常
NSOperationQueuePriorityHigh = 4,// 优先级高
NSOperationQueuePriorityVeryHigh = 8// 优先级很高
};

e.g.:上面的例子,是第二张图片先下载的,是先执行operation2的,如果在把操作放在队列中之前设置operation1 的优先级为很高,就可以做到先下载第一张图片,先执行operation1。

operation1.queuePriority = NSURLSessionTaskPriorityHigh;

日志:

2016-11-12 10:00:04.114 TTTTTTTTTT[4219:55622] 下载第一张图片<NSThread: 0x6080002613c0>{number = 3, name = (null)}
2016-11-12 10:00:04.115 TTTTTTTTTT[4219:55611] 下载第二张图片<NSThread: 0x600000075340>{number = 4, name = (null)}
2016-11-12 10:00:04.267 TTTTTTTTTT[4219:55644] 合并图片<NSThread: 0x600000264900>{number = 6, name = (null)}

注意:优先级高的就一定会最先执行吗?不一定,这个例子比较简单,不能代表全部。优先级高只是提供了一个可能,至于会不会最先执行,还要看CPU的使用情况、操作的复杂程度和队列。同理,优先级低的也不一定会最后执行。

3.操作的取消、执行、完成

NSOperation的三个属性cancelled、executing、finished,分别就是取消,执行,完成。这三个属性都是只读的,我们通过这三个属性可以判断NSOperation的状态,是否取消了,是否正在执行,是否已经完成了。

4.completionBlock

如果你想在操作(operation)完成之后执行一些代码,可以写在这个block块里面。

operation.completionBlock = ^{
NSLog(@"我完成了");
};

注意:如果你把操作(operation)放入队列(queue)里面了,这行代码一定要放在添加之前,否则不执行。

5队列的最大并发数

@property NSInteger maxConcurrentOperationCount;

  这是NSOperationQueue的一个属性。由于NSOperationQueue里的操作都是并发的,所以我们可以设置同时并发多少个操作。如果不设置,系统默认。

queue.maxConcurrentOperationCount = 3;

注意:这个属性最好不要设置,系统默认就好。如果设置,最好不要超过5,最好是2-3。如果设置的太大, 会卡顿UI。因为CPU在多个线程之间切换,线程太多,什么时候才能轮到主线程刷新UI啊!。

6.队列的暂停、恢复、取消

1)暂停:

[queue setSuspended:YES];

2)恢复:

[queue setSuspended:NO];

3)判读队列的当前状态:

@property (getter=isSuspended) BOOL suspended;

  当你把队列暂停时,队列里的操作就不执行了。当你滑动列表时,可以先把队列(队列里执行下载图片的操作,列表里的cell上有图片)暂停,不滑动时再恢复,增加APP的流畅性。

4)取消所有操作

- (void)cancelAllOperations;

  队列里的所有操作都不执行了。

  以上就是关于NSOperation的常用操作,用这些基本上就能够满足我们的需求。如果还满足不了怎么办,自定义NSOperation,下一篇文章讲自定义NSOperation。

iOS多线程之8.NSOPeration的其他用法的更多相关文章

  1. iOS多线程之7.NSOperation的初识

    NSOperation和GCD一样,不用我们管理线程的生命周期,加锁等问题,只要把操作封装进NSOperation中,系统会自动帮我们创建线程,执行操作.而且他是面向对象的,我们看起来更容易理解,使用 ...

  2. iOS多线程之6.GCD的其他用法

    队列组   让队列里的任务同时执行,当任务都执行完毕时,再以通知的形式告诉程序员.举例,同时下载两张图片,两张图片都下载完了,在合成成一张. 代码: #import "ViewControl ...

  3. iOS多线程之GCD小记

    iOS多线程之GCD小记 iOS多线程方案简介 从各种资料中了解到,iOS中目前有4套多线程的方案,分别是下列4中: 1.Pthreads 这是一套可以在很多操作系统上通用的多线程API,是基于C语言 ...

  4. iOS多线程之Thread

    多线程 • Thread 是苹果官方提供的,简单已用,可以直接操作线程对象.不过需要程序员自己管理线程的生命周期,主要是创建那部分 优缺点 面向对象,简单易用 直接操作线程对象 需要自己管理线程生命周 ...

  5. iOS多线程之GCD、OperationQueue 对比和实践记录

    [toc] 简介      在计算的早期,计算机可以执行的最大工作量是由 CPU 的时钟速度决定的.但是随着技术的进步和处理器设计的紧凑化,热量和其他物理约束开始限制处理器的最大时钟速度.因此,芯片制 ...

  6. iOS多线程之NSOperation详解

    使用NSOperation和NSOperationQueue进行多线程开发,只要将一个NSOperation(实际开发中需要使用其子类 NSInvocationOperation,NSBlockOpe ...

  7. iOS 多线程之NSOperation篇举例详解

    这篇博客是接着总篇iOS GCD NSOperation NSThread等多线程各种举例详解写的一个支篇.总篇也包含了此文的链接.本文讲解的知识点有NSBlockOperationClick,队列, ...

  8. iOS多线程之9.自定义NSOperation

      本文主要讲如何自定义NSOperation,以及自定义NSOperation的一些注意事项,以下载图片为例. 新建一个类,继承于NSOperation. CustomOperation.h 代码 ...

  9. IOS多线程之NSOperation学习总结

    NSOperation简介 1.NSOperation的作用 配合使用NSOperation和NSOperationQueue也能实现多线程编程 2.NSOperation和NSOperationQu ...

随机推荐

  1. hibernate-mapping-3.0.dtd;hibernate-configuration-3.0.dtd;hibernate.properties所在路径

    hibernate-mapping-3.0.dtd 所在路径:hibernate-release-5.2.5.Final\project\hibernate-core\src\main\resourc ...

  2. 机器指令翻译成 JavaScript —— No.5 指令变化

    上一篇,我们通过内置解释器的方案,解决任意跳转的问题.同时,也提到另一个问题:如果指令发生变化,又该如何应对. 指令自改 如果指令加载到 RAM 中,那就和普通数据一样,也是可以随意修改的.然而,对应 ...

  3. 【开源】知乎日报UWP 更新

    说明 大概十天之前我更新了一次APP,后来又仔细看了一下Store里的评论,发现还有几个地方没有改过来.于是前天晚上抽时间改了一下,顺便完善了一下UI体验. 没有看前面文章的童鞋可以看一下下面的链接: ...

  4. 深入解析js异步编程利器Generator

    我们在编写Nodejs程序时,经常会用到回调函数,在一个操作执行完成之后对返回的数据进行处理,我简单的理解它为异步编程. 如果操作很多,那么回调的嵌套就会必不可少,那么如果操作非常多,那么回调的嵌套就 ...

  5. 4.修改更新源sources.list,提高软件下载安装速度(提供Kali 2.0 更新源)

    1.切换到root用户(如果已经是root用户就直接看第二步) dnt@HackerKali:~$ su 密码: 2.用文本编辑器打开sources.list,手动添加下面的更新源 root@Hack ...

  6. 逆向工程 - Reveal、IDA、Hopper、HTTPS抓包 等

    目录: 一. iOS 如何做才安全 二.ipa文件 三.沙盒 中的数据 四.Reveal:查看 任何APP 的UI结构 五.反编译工具:IDA 六.反编译工具:Hopper Disassembler ...

  7. [SQL] SQL 基础知识梳理(一)- 数据库与 SQL

    SQL 基础知识梳理(一)- 数据库与 SQL [博主]反骨仔 [原文地址]http://www.cnblogs.com/liqingwen/p/5902856.html 目录 What's 数据库 ...

  8. C++程序员如何转Java

     C++程序员如何转Java 忙里偷闲,到了这个时间终于得空写一篇早想写的文章.其实本文的标题有些不太准确,C++程序员写Java代码不是说就非得转行写Java,抛弃C++,而只是多了一个选择而已.两 ...

  9. ASP.NET Core 中文文档 第四章 MVC(3.1)视图概述

    原文:Views Overview 作者:Steve Smith 翻译:姚阿勇(Dr.Yao) 校对:高嵩(Jack) ASP.NET MVC Core 的控制器可以利用 视图 返回格式化结果. 什么 ...

  10. scrapy cookies:将cookies保存到文件以及从文件加载cookies

    我在使用scrapy模拟登录新浪微博时,想将登录成功后的cookies保存到本地,下次加载它实现直接登录,省去中间一系列的请求和POST等.关于如何从本次请求中获取并在下次请求中附带上cookies的 ...