SDWebimage相关知识点1-- NSOperation

GCD

GCD是最常用的管理并行代码和执行异步操作的Unix系统层的API。GCD构造和管理队列中的任务。

队列是按先进先出(FIFO)管理对象的数据结构。队列类似电影院的售票窗口,票的销售是谁先到谁先服务。在等待线前面的人先去买他们的门票,在其余的后抵达的人之前。队列在计算机科学中是相似的,因为第一个添加到队列的对象也是第一个从队列中删除的对象。

操作队列  NSOperationQueue

GCD是一个底层的C的API,它使开发人员能够并行地执行任务。操作队列,另一方面,是高度抽象的队列模型,是建立在GCD之上的。这意味着你可以并行执行任务就像GCD一样,但以面向对象的方式。简而言之,队列操作让编程更加简单。

不同于GCD,它们不按先进先出的顺序。下面是操作队列和调度队列的不同点:

1.不遵循先进先出:在操作队列中,你可以设置一个操作的执行优先级,你可以添加操作之间的依赖关系,这意味着你可以定义一些操作完成后才会执行其他操作。这就是为什么它们不遵循先进先出。

2.默认情况下,它们同时操作:然而你不能把它的类型改变成串行队列。通过使用操作之间的依赖关系,在操作队列还存在一个工作区来依次执行任务。

3.操作队列是类NSOperationQueue的实例,其任务封装在NSOperation的实例里。

NSOperation

是苹果提供的一套多线程解决方案,实际上NSOperation是基于GCD 更高一层的封装,但是比GCD 更简单易用、代码可读性更高。

需要配合NSOperationQueue 来实现多线程。 默认情况下,单独使用NSOperation时系统执行同步操作,并没有开辟新线程的能力,只有和配合NSOperationQueue 才能实现异步执行。

因为NSOperation是基于GCD的,那么使用起来也和GCD差不多,其中,NSOperation相当于GCD中的任务,而NSOperationQueue则相当于GCD中的队列。NSOperation实现多线程的使用步骤分为三步:

  1. 创建任务:先将需要执行的操作封装到一个NSOperation对象中。
  2. 创建队列:创建NSOperationQueue对象。
  3. 将任务加入到队列中:然后将NSOperation对象添加到NSOperationQueue中。

之后呢,系统就会自动将NSOperationQueue中的NSOperation取出来,在新线程中执行操作。

NSOperation是一个抽象类,它不能直接使用,所以你必须使用NSOperation子类。在iOS SDK里,我们提供两个NSOperation的具体子类。这些类可以直接使用,但你也可以继承NSOperation来创建自己的类来执行操作。我们可以直接使用的两个类:

1.NSBlockOperation——使用这个类来用一个或多个block初始化操作。操作本身可以包含多个块。当所有block被执行操作将被视为完成。

2.NSInvocationOperation——使用这个类来初始化一个操作,它包括指定对象的调用selector。

或者定义继承自NSOperation的子类,通过实现内部相应的方法来封装任务。

NSOperationQueue

和GCD中的并发队列、串行队列不同的是,NSOperationQueue 一共有两种队列:主队列、其他队列。

其他队列中包含了串行、并发功能。

NSOperationQueue *queue = [NSOperationQueue mainQueue];//主队列

NSOperationQueue *queue = [[NSOperationQueue alloc] init];//其他队列

将任务加入到队列中

1.先创建任务,再将创建好的任务加入到创建好的队列中去

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

2.无需创建任务,在block中执行任务,直接将任务block加入到队列中

(void)addOperationWithBlock:(void (^)(void))block;

控制串行执行和并发执行的关键

最大并发数:maxConcurrentOperationCount

默认情况下是-1,表示不进行限制,默认为并发执行。

当为1时,进行串行执行。

当>1时,进行并发执行。

操作依赖

NSOperation和NSOperationQueue最吸引人的地方是它能添加操作之间的依赖关系。比如说有A、B两个操作,其中A执行完操作,B才能执行操作,那么就需要让B依赖于A。

- (void)addDependency

一些其他的方法:

  • - (void)cancel; NSOperation提供的方法,可取消单个操作
  • - (void)cancelAllOperations; NSOperationQueue提供的方法,可以取消队列的所有操作
  • - (void)setSuspended:(BOOL)b; 可设置任务的暂停和恢复,YES代表暂停队列,NO代表恢复队列
  • - (BOOL)isSuspended; 判断暂停状态

注意:

这里的暂停和取消并不代表可以将当前的操作立即取消,而是当当前的操作执行完毕之后不再执行新的操作

  • 暂停和取消的区别就在于:暂停操作之后还可以恢复操作,继续向下执行;而取消操作之后,所有的操作就清空了,无法再接着执行剩下的操作。

自定义子类:

使用main方法,不需要管理一些状态属性(如isExecuting 和 isFinished ),当main 方法返回的时候,这个operation 就结束了。 这种方式使用起来非常简单,main方法执行完就认为operation 结束了。所以一般可以用来执行同步任务。

如果你希望拥有更多的控制权,或者想在一个操作中可以执行异步任务,那么就重写start 方法。

在这种情况下,必须手动管理操作的状态,只有当发送isFinished 的kvo 消息时,才认为是operation 结束。

所以NSOperation的优势是什么?

1.首先,它们通过NSOperation类里的方法addDependency(op:NSOperation)支持依赖。当你需要开始一个依赖于其它操作执行的操作,你会需要NSOperation。

2.其次,你可以通过下面这些值设置属性queuePriority来改变执行优先级:

3.对于任何给定的队列,你可以取消一个特定的或所有的操作。操作可以在被添加到队列后被取消。取消是通过调用NSOperation类里的方法cancel()。当你取消任何操作的时候,我们有三个场景,其中一个会发生:

你的操作已经完成。在这种情况下,取消方法没有效果。

你的操作已经被执行。在这种情况下,系统不会强制操作代码停止,而是属性cancelled被置为true。

你的操作仍在队列中等待。在这种情况下,你的操作将不会被执行。

4.NSOperation有3个有用的布尔属性,finished、 cancelled和ready。一旦操作执行完成,finisher将被置为true。一旦操作被取消,cancelled将被置为true。一旦准备即将被执行,ready将被置为true。

5.任何NSOperation有一个选项来设置回调,一旦任务完成将会被调用。在NSOperation里,一旦属性finished被置为true,这个block将被调用。

原理探析:

demo:

- (void)viewDidLoad {

[super viewDidLoad];

// Do any additional setup after loading the view, typically from a nib.

[self configurationQueue];

LDNSOperation *operation = [[LDNSOperation alloc] init];

[self.operationQueue addOperation:operation];

[NSThread sleepForTimeInterval:3];

[operation cancel];

}

-(void)configurationQueue{

self.operationQueue = [[NSOperationQueue alloc] init];

self.operationQueue.maxConcurrentOperationCount = 4;

}

LDNSOperation为NSOperation的子类,重写start方法:

-(void)start{

while (true) {

if(self.cancelled){

NSLog(@"已经取消");

return;

}

NSLog(@"start");

[NSThread sleepForTimeInterval:1];

}

}

1.

[self.operationQueue addOperation:operation];

添加一个未完成的NSOperation ,其实就是将NSOperation 添加到一个动态的数组中。

internal 就是一个内部类,指的是NSOperationQueue 。

使用了KVO手动通知,进行operations 和 operationCount 的改变通知。

完成的话,就从operations 中删除。

如果准备完成,就添加到waiting 中,等待被执行。

_execute 方法:

如果没有暂停,就从waiting 中取出第一个,并且删除waiting 中的这个数据。

添加isFinished 属性观察

如果是并发的话,就马上执行。

如果不是,使用detachNewThreadSelector来创建新的线程去执行start。

所有的线程都很忙,并且没有达到threadCount最大值时,会创建新的线程。

_execute 是一个执行队列,依次将等待队列里所有的operation 进行start 。

对于start 函数来讲,一个NSOperation 并没有新建一个线程。 依然操作在[NSTread currentThread]中。

现在来思考下,也就明白了为什么NSOperationQueue要有两种处理方式了,如果NSOperation支持并发,然后NSOperationQueue在为其分配线程,那就是线程里面又跑了一条线程,这样就很尴尬了,通过isConcurrent可以避免这种现象。

原文地址:https://www.cnblogs.com/JShuo/p/8678192.html

时间: 2024-11-01 10:17:29

SDWebimage相关知识点1-- NSOperation的相关文章

SDWebimage相关知识点1-- 线程

一 线程(thread)是组成进程的子单元,操作系统的调度器可以对线程进行单独的调度.实际上,所有的并发编程 API 都是构建于线程之上的 -- 包括 GCD 和操作队列(operation queues). 多线程可以在单核 CPU 上同时(或者至少看作同时)运行.操作系统将小的时间片分配给每一个线程,这样就能够让用户感觉到有多个任务在同时进行.如果 CPU 是多核的,那么线程就可以真正的以并发方式被执行,从而减少了完成某项操作所需要的总时间. NSThread 是 Objective-C 对

垂直搜索的相关知识点总结

垂直搜索引擎大体上需要以下技术 1.Spider 2.网页结构化信息抽取技术或元数据采集技术 3.分词.索引 4.其他信息处理技术 垂直搜索引擎的技术评估应从以下几点来判断 1.全面性 2.更新性 3.准确性 4.功能性 垂直搜索的进入门槛很低,但是竞争的门槛很高.没有专注的精神和精湛的技术是不行的.行业门户网站具备行业优势但他们又是没有技术优势的,绝对不要想像着招几个人就可以搞定垂直搜索的全部技术,作为一个需要持续改进可运营的产品而不是一个项目来说对技术的把握控制程度又是垂直搜索成功的重要因素

博客6:磁盘以及创建文件系统的相关知识点

1.linux磁盘的相关知识点  (1)I/O ports:I/O设备地址,实质上是一个缓冲器  (2)块设备:Block,存取单位是"块",例如:磁盘  (3)字符设备:char,存取单位是"字符",例如:键盘  (4)设备文件:关联至一个设备驱动程序,进而能够与之对应硬件设备进行通信(仅有元数据,而无数据)  (5)设备号码:              主设备号:major number,表示设备类型              次设备号:minor number

图像处理程序框架—MFC相关知识点

CDC:Windows使用与设备无关的图形设备环境(DC :Device Context) 进行显示 . MFC基础类库定义了设备环境对象类----CDC类.CDC与CGdiObject的关系 说道CDC类就不能不提一下GdiObject---图形对象类. 在Windows应用程序中,设备环境与图形对象共同工作,协同完成绘图显示工作.就像画家绘画一样,设备环境好比是画家的画布,图形对象好比是画家的画笔.用画笔在画布上绘画,不同的画笔将画出不同的画来.选择合适的图形对象和绘图对象,才能按照要求完成

libgdx相关知识点

Gdx.graphics.setContinuousRendering(false); 设置图像为非连续自动渲染. libgdx相关知识点,布布扣,bubuko.com

Android开发涉及有点概念&相关知识点(待写)

前言,承接之前的 IOS开发涉及有点概念&相关知识点,这次归纳的是Android开发相关,好废话不说了.. 先声明下,Android开发涉及概念比IOS杂很多,可能有很多都题不到的.. 首先由于Android是基于Linux,而Linux又是用c山寨Unix的,但是为什么Android不用开发App,其实我也不懂,我想可能是java比较简单. 同样的,IOS为啥没用java,这个我也想可能是因为IOS是封闭的吧..晕,又废话了..好,开始吧,不过这次很多要查资料了,很多名词.单词不会啊! 首先还

<c:url>标签相关知识点

一. <c:url>标签的作用主要用来产生字符串类型的url,而不是产生一个超链接,注意url(统一资源定位符)与超链接两个含义的区别. <c:url value="http://www.baidu.com" />在JSP页面中的输出形式如下: 可以看出来这在页面中就是个字符串,不是一个能点击的超链接. --------------------------------------------------------------------------------

学习记录013-NFS相关知识点

一.NFS相关知识点 1.NFS常用的路径/etc/exports NFS服务主配置文件,配置NFS具体共享服务的地点/usr/sbin/exportfs NFS服务的管理命令,exportfs -arv 可以通过加载配置生效,也可以通过命令直接共享目录,越过/etc/exports,但是重启失效/usr/sbin/showmount 常用来在客户端,查看NFS配置及挂载结果的命令/var/lib/nfs/etab NFS配置文件的完整参数设定的文件注意:如果需要读写共享,一定要让本地目录被NF

Python开发一个csv比较功能相关知识点汇总及demo

Python 2.7 doc demo: # -*- coding: utf-8 -*- import csv with open('eggs.csv', 'wb') as csvfile: spamwriter = csv.writer(csvfile, delimiter=' ', quotechar='|', quoting=csv.QUOTE_MINIMAL) spamwriter.writerow(['Spam'] * 5 + ['Baked Beans']) spamwriter.w