NSOperationQueue简介

一、NSOperationQueue简介

1.概述:
 NSOperationQueue类管理NSOperation对象的执行。NSOperationQueue可以被称为操作队列,NSOperation可以被称为操作。操作被添加到操作队列之后,操作队列会根据操作对象的优先级或者相互之间的依赖关系来执行操作。一个应用程序可以创建多个操作队列,每个操作队列分别管理若干操作。

2.什么时候操作会被移除:
 当操作被添加到队列中以后,我们不能从操作队列中直接移除操作对象。当一个操作对象的任务完成之后才会被自动移除。任务完成的含义:操作的start方法被调用,并且isFinished方法返回YES。

3.如何取消任务执行:
调用操作对象cancel方法并不能使操作马上停止执行。当NSOperation的cancel方法被调用后,如果操作不在队列中,这个方法会将操作的isFinished设为YES,如果在操作队列中,这个方法会将操作对象的isCancelled状态设为YES,并且isReady设为YES,让队列调用它的start方法。在start或者main方法实现中,我们应该检查isCancelled和isFinished属性,如果任意一个为YES,就不执行操作,直接返回,如果是并发操作,让isFinished方法返回YES,如果是非并发操作,设置isFinished值为YES。

4.操作队列的相关API:
(1)创建队列:
可以调用[[NSOperationQueue alloc] init]方法新建一个操作队列,或者调用类方法currentQueue、mainQueue方法获取现存的操作队列。currentQueue一般在NSOperation对象子类中调用,用来返回启动当前操作的队列,如果NSOperation在非运行状态或者在NSOperation外部调用此方法,一般会返回nil。mainQueue方法返回和主线程绑定的操作队列。
(2)增加操作:
addOperation:  增加一个操作对象。
addOperations:waitUntilFinished: 增加一个操作对象数组,可以阻塞当前线程等待所有操作完成。
addOperationWithBlock: 以block的方式添加操作,blcok必须为无参数无返回数据。
(3)最大并发数:
maxConcurrentOperationCount :最大并发数属性,默认为-1,表示并发数无限制,由系统根据环境条件动态决定。
setMaxConcurrentOperationCount:设置最大并发数。
(4)其它:
operations :获取添加到队列中的所有操作对象。
operationCount :获取添加到队列中的操作对象的数量。
setSuspended: 设置队列是否暂停安排操作执行。
isSuspended :获取队列是否处在暂停安排操作执行的状态。
cancelAllOperations:调用所有操作对象的cancel方法。
waitUntilAllOperationsAreFinished:阻塞当前线程,等待所有操作都完成。

5.KVO兼容的属性
operations - 只读
operationCount - 只读
maxConcurrentOperationCount - 可读写
suspended - 可读写
name -可读写

6.内部实现:
 在iOS4.0及以后,NSOperationQueue内部实现使用GCD,iOS4.0之前,使用NSThread实现。

二、NSOperation简介

1.概述:
NSOperation类代表单个任务对象,是一个抽象类,因此他不能直接使用它,可以实现它的子类,也可以使用类库中已存在的子类,比如NSInvocationOperation和NSBlockOperation,可以比较简单的创建操作对象。操作对象只能被执行一次,只要被执行过,就不能再重新执行第二次。

2.依赖关系:
(1)调用NSOperation的addDependency或者removeDependency可以给一个操作对象添加一个它所依赖的操作对象、删除一个所依赖的操作对象。调用dependencies方法可以获取一个操作所依赖的所有操作对象。
(2)只有当一个操作对象的所有依赖对象都执行完毕后,它的isReady属性才可能会成为YES,从而被队列执行。
(3)NSOperation本身并不区分它的依赖对象是执行失败还是成功,只判断操作是否执行完毕(即有可能是通过cancel方法完成的)。
(4)如果一个操作对象被调用了cancel方法,但是还有它依赖的操作对象没有完成,它所依赖的操作对象将被忽略,当前操作对象不再等待它们完成。

3.执行优先级
(1)调用queuePriority、setQueuePriority:方法可以获取和设置操作对象的执行优先级。
(2)类库中定义了几个优先级变量:
   NSOperationQueuePriorityVeryLow
   NSOperationQueuePriorityLow
   NSOperationQueuePriorityNormal
   NSOperationQueuePriorityHigh
   NSOperationQueuePriorityVeryHigh
   最高对应的数字为8,最低-8,如果手动设置数字,setQueuePriority方法会自动切换成对应的最合适的数字。
(3)优先级只表示此操作对象的优先级和其它对象优先级的大小关系,不能精确定义两个对象的执行顺序,不能使用优先级这个方式来实现依赖关系。

4.KVO兼容的属性
isCancelled - 只读,操作是不是被取消,cancel方法会改变此变量。
isConcurrent - 只读,是不是并发
isExecuting - 只读,是不是正在执行
isFinished - 只读,是不是已经完成
isReady - 只读,是不是已经准备好执行
dependencies - 只读,操作对象的依赖关系
queuePriority - 可读写,操作对象在队列中的优先级
completionBlock - 可读写,操作完成之后执行的Block

5.并发操作和非并发操作
(1)如果打算手动执行操作对象,我们可以把操作对象设计成非并发的,也可以涉及成并发的。操作对象默认是非并发的。
(2)在非并发的操作对象中,操作任务是以同步的方式实现的,当调用start方法时,任务在当前线程执行,当start方法返回时,任务已经完成,执行期间线程被阻塞。
(3)并发操作对象的任务以异步的方式执行,当调用start方法时,start方法立即返回,不阻塞当前线程。因为在start方法中,任务代码使用新线程或者异步API实现。
(4)如果打算总是以队列的方式执行操作,最简单的方式是将操作对象设计成非并发的。定义并发操作对象需要更过的工作,因为实现并发操作对象需要实现更多的方法,而且我们必须去监听任务的状态以及使用KVO手动通知的方式报告状态。当非并发操作在队列中执行时,队列会自动建立新线程来执行操作,最后结果也是异步的。所以如果总是以队列的方式执行操作对象,是没有理由使用并发操作的。

6.子类化NSOperation
(1)如果是非并发操作,只需要实现main方法即可。
(2)如果是并发操作,最少要实现一下四个方法:start、isConcurrent、isExecuting、isFinished。
(3)在main方法和start方法实现中,在开始执行任务代码前,首先应该检查对象状态,如果
isCancelled等于YES或者isFinished等于YES,则不用执行任务代码。如果是并发操作,让isFinished方法返回YES,如果是非并发操作,设置isFinished值为YES。
(4)在重写isConcurrent、isExecuting、isFinished方法的同时,还要对值发生改变的key使用KVO手动的方式触发通知,否则操作不会被认为执行结束。代码逻辑:在以上三个方法中通过判断本地的状态标记变量来判断状态值,并返回;在更改我们的本地标记变量值时,通过KVO发送通知,然后OperationQueue就会去调用以上三个方法来判断Operation执行状态,如果isFinished方法返回YES,则操作完成,任务结束。

7.异步NSOperation实现示例:

typedef enum

{

    RequestStateReady = 0,

    RequestStateExecuting,

    RequestStateFinished

}RequestState;


@interface RequestOperation ()


@property(nonatomic,strong) NSURLConnection *connection;

@property(nonatomic,strong) NSMutableData *resultData;

@property(nonatomic,assign) RequestState requestState;


@end


@implementation RequestOperation


-(id)init{

    self = [super init];

    if (self) {

        [self willChangeValueForKey:@"isReady"];

        self.requestState = RequestStateReady;

        [self didChangeValueForKey:@"isReady"];

    }

    return self;

}


#pragma mark - Operation实现父类方法


-(void)start{

    [self exeRequest];

}


-(BOOL)isConcurrent{

    return YES;

}


-(BOOL)isReady{

    return self.requestState == RequestStateReady && [super isReady];

}


-(BOOL)isExecuting{

    return self.requestState == RequestStateExecuting;

}


-(BOOL)isFinished{

    return self.requestState == RequestStateFinished;

}


#pragma mark - 发起请求


-(void)exeRequest{

    if (self.isCancelled == YES || self.isFinished == YES) {

        return;

    }

    

    NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://www.baidu.com/"]];

    self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

    [self.connection start];

    [[NSRunLoop currentRunLoop] run];

    

    [self willChangeValueForKey:@"isExecuting"];

    self.requestState = RequestStateExecuting;

    [self didChangeValueForKey:@"isExecuting"];

}


#pragma mark - 请求代理实现


-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{

    self.resultData = [[NSMutableData alloc] initWithCapacity:0];

}


-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{

    [self.resultData appendData:data];

}


-(void)connectionDidFinishLoading:(NSURLConnection *)connection{

    [self willChangeValueForKey:@"isFinished"];

    self.requestState = RequestStateFinished;

    [self didChangeValueForKey:@"isFinished"];

}


-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{

    [self willChangeValueForKey:@"isFinished"];

    self.requestState = RequestStateFinished;

    [self didChangeValueForKey:@"isFinished"];

}


@end

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/500142.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机 窗口打开的方法,如何打开命令行窗口?两种实用的方法介绍

Windows系统中常常会用到命令行窗口,那么我们该如何打开命令行窗口?接下来,小编为大家介绍两种实用的打开命令行窗口的技巧,再也不必担忧如何打开命令行窗口的烦恼了。第一种打开方法1.点击自己的电脑中的开始菜单,在菜单中找到运…

GCD简介一:基本概念和Dispatch Queue

一、什么是GCD?Grand Central Dispatch或者GCD,是一套低层API,提供了一种新的方法来进行并发程序编写。从基本功能上讲,GCD有点像NSOperationQueue,他们都允许程序将任务切分为多个单一任务然后提交至工作队列来并发地…

大学生计算机二级大集报名最好,在校大学生如何报名计算机二级?

2009-12-05 回答首先要根据你的所学专业来衡量自己考哪项计算级二级有c语言, vb, vf, java, access, c 六项可选考其中一个你会的 考下来能拿计算机二级了考试分两部分,上机和笔试。笔试就是一些基本的操作…

GCD简介二:多核心的性能

一、概念为了在单一进程中充分发挥多核的优势,我们有必要使用多线程技术。在低层,GCD全局dispatch queue仅仅是工作线程池的抽象。这些队列中的Block一旦可用,就会被dispatch到工作线程中。提交至用户队列的Block最终也会通过全局队列进入相同…

怪哉翻译软件测试,[东方朔传翻译]东方朔传·怪哉原文与翻译

东方朔传怪哉原文与翻译原文:《太平广记》卷四七三引《东方朔传》汉武帝幸⑦甘泉,驰道中有虫,赤色,头牙齿耳鼻尽具,观者莫识①。帝乃使东方朔视之,还对②曰:“此虫名怪哉。昔时拘系⑧无辜&#…

GCD简介三:Dispatch Sources

一、何为Dispatch Sources简单来说,dispatch source是一个监视某些类型事件的对象。当这些事件发生时,它自动将一个block放入一个dispatch queue的执行例程中。我们到底讨论哪些事件类型?下面是GCD 10.6.0版本支持的事件:Mach por…

GCD简介四:挂起,目标指定,信号量

一、Dispatch Queue挂起dispatch queue可以被挂起和恢复。使用 dispatch_suspend函数来挂起,使用 dispatch_resume 函数来恢复。这两个函数的行为是如你所愿的。另外,这两个还是也可以用于dispatch source。一个要注意的地方是,dispatch que…

如何自己做网站发布到服务器上面,怎么做网站 四步教你搭建自己的网站

1、购买域名如果想要做一个自己的网站,购买一个自己喜欢的域名就是首先要做的!当你购买好自己的域名,就走出了搭建自己网站的第一步!2、购买空间/主机/服务器空间/主机/服务器,看着好像很复杂,其实很简单&a…

GCD简介五:补充

1.GCD在iOS4.0及以上可用。2.GCD中,主线程队列是串行的;全局队列是并行的,并由整个进程共享;用户自建队列,在iOS4.3以下,只能是串行,iOS4.3及以上,可以是并行的。3.dispatch_suspend…

ajax delete 传递参数,springMVC使用PUT、DELETE方法传递参数解决方案

在web.xml中新增过滤器HiddenHttpMethodFilterorg.springframework.web.filter.HiddenHttpMethodFilterHiddenHttpMethodFilter/*需要注意的是,只有context-type:application/x-www-form-urlencoded的请求才会被过滤。该过滤器的核心方法如下&#xff1a…

ARC简介

1、简介:ARC(Automatic Reference Counting),自动引用计数,需要XCode4.2和SDK5.0的支持。它是一个在编译期间工作的技术,编译器在编译的时候会根据变量的作用域为objective-c变量添加合适的retain、release、autorelease等函数。原…

微信验证码无法连接到服务器,微信无法连接到服务器1237解决方法

太多朋友在使用微信过程中出现微信无法连接到服务器1237的问题,出现这个问题的原因有很多种,接下来小编带大家找出问题原因,然后成功解决这个问题。以下是网友们成功解决此问题的方法,大家可以参考一下方法一:首先重启…

iOS后台任务

一、概览1.从iOS4.0开始,系统添加了多任务特征,允许应用在按下Home键之后,继续执行后台任务。大部分应用在进入后台之后就进入了挂起状态,只有那些为用户提供重要服务的App能够在进入后台之后继续运行一段时间。2.一般情况下&…

王者荣耀服务器维护bug,8月23日王者荣耀ios版更新一直显示维护是什么情况?更新出现bug 附处理方法...

相信很多喜爱玩王者荣耀的游戏玩家可以知道今天是王者荣耀星计划更新的日子,但是有很多苹果手机的小伙伴出现了一个问题,那就是无法进入游戏,甚至是更新十分的缓慢,在这里本文为您带来最新的解决方法!苹果手机微信区一…

服务器任务栏不显示程序,Win10任务栏不显示应用程序标签怎么办?

Win10任务栏不显示应用程序标签怎么办?执拗的人才会一条路走到黑,多个朋友多条路,多个方法多种选择。关于Win10任务栏不显示应用程序标签,一般是explorer进程出现故障导致,哦!忘记说了Win10系统下这东东改了个好听的名字&#xf…

Objective-C复制解析

一、为什么使用复制?1.C语言以及Objective-C语言总是按值传递的,按值传递意味着是隐式复制。在这里就分为两种情况:(1)如果是非对象类型,对传递过来的值进行更改,只会更改副本,对原始值没有影响&#xff0c…

udp协议的服务器是哪种类型,UDP协议

UDP协议1.UDP使用场景域名系统若是执行时间内,没有响应返回,证明包已丢失。音频或视频数据包的丢失只会造成通话或视频的干扰和不清楚,而不会像TCP协议那样造成通话的丢失或卡顿。2.UDP和TCP的类比UDP类似于邮局,数据的接受与否和…

归档和解档-Archiver

一、概念1.归档用于保存对象,包括被归档对象之间的各种相互关系或者依赖性。解档用于重建以前归档的对象与关系。在其它面向对象的语言中,一般使用术语"序列化"来描述归档解档模式。2.归档的对象通常存储为二进制数据,可以在内存或…

碧雪情天服务器地址源如何修改,稀有游戏《碧雪情天online》网络版王者归来一键服务端+客户端 支持转生系统和新图...

碧雪情天online王者归来版本介绍:1.增加新的职业套装;2.增加高川台、雪域、魔灵和天庭等新图;3.仙侠岭先知处添加角色转生功能;4.碣石村宝官添加装备签名和祝福卡兑换角色经验功能;5.增加宠物经验兑换角色经验功能;6.其它新内容和…

Objective-C单例

一、要点:1.当在应用程序中只需要有类的一个实例,并且可以被其它对象轻松的访问的时候,可以使用单例类。2.首先需要声明一个静态的类的实例变量,并初始化为nil。应该将该实例变量声明在类的实现文件中,表示变量仅在该实…