可以设置队列中每一个操作的 QOS() 队列的整体 QOS 操作相关 Operation作为一个对象,为我们提供了更多的选择: 任务依赖(addDependency),可以跨队列设置操作的依赖关系 ,按优先级执行;存在依赖时,按依赖关系先后执行(与无依赖关系的其他任务相比,依赖集合的执行顺序不确定) 队列暂停/继续 通过对队列的isSuspended属性赋值,可实现队列中未执行任务的暂停和继续效果 如果操作对象的执行顺序对您很重要,那么您应该在将操作添加到队列之前使用 依赖关系 建立该顺序,或改用 GCD 的 串行队列 实现序列化效果。 常见问题 如何解决资源竞争问题 资源竞争可能导致数据异常,死锁,甚至因访问野指针而崩溃。 对于有明显先后依赖关系的任务,最佳方案是 GCD串行队列,可以在不使用线程锁时保证资源互斥。 您可以考虑为每个需要资源的客户机制作资源的副本,或者完全消除该资源。 不使用锁来保护某些共享资源,而是指定一个 串行队列 (或使用操作对象依赖项)以正确的顺序执行任务。 避免使用 锁。
通过本文,您将了解到: NSOperation、NSOperationQueue 简介、操作和操作队列、使用步骤和基本使用方法、控制串行/并发执行、NSOperation 操作依赖和优先级、线程间的通信 为什么要使用 NSOperation、NSOperationQueue? 可添加完成的代码块,在操作完成后执行。 添加操作之间的依赖关系,方便的控制执行顺序。 设定操作执行的优先级。 NSOperationQueue 对于添加到队列中的操作,首先进入准备就绪的状态(就绪状态取决于操作之间的依赖关系),然后进入就绪状态的操作的开始执行顺序(非结束执行顺序)由操作之间相对的优先级决定(优先级是操作对象自身的属性 NSOperation 操作依赖 NSOperation、NSOperationQueue 最吸引人的地方是它能添加操作之间的依赖关系。通过操作依赖,我们可以很方便的控制操作之间的执行先后顺序。 如果要控制操作间的启动顺序,则必须使用依赖关系。 8.
提供包括云服务器,云数据库在内的90+款云计算产品。打造一站式的云产品试用服务,助力开发者和企业零门槛上云。
通过本文,您将了解到: NSOperation、NSOperationQueue 简介、操作和操作队列、使用步骤和基本使用方法、控制串行/并发执行、NSOperation 操作依赖和优先级、线程间的通信 为什么要使用 NSOperation、NSOperationQueue? 可添加完成的代码块,在操作完成后执行。 添加操作之间的依赖关系,方便的控制执行顺序。 设定操作执行的优先级。 NSOperationQueue 对于添加到队列中的操作,首先进入准备就绪的状态(就绪状态取决于操作之间的依赖关系),然后进入就绪状态的操作的开始执行顺序(非结束执行顺序)由操作之间相对的优先级决定(优先级是操作对象自身的属性 NSOperation 操作依赖 NSOperation、NSOperationQueue 最吸引人的地方是它能添加操作之间的依赖关系。通过操作依赖,我们可以很方便的控制操作之间的执行先后顺序。 如果要控制操作间的启动顺序,则必须使用依赖关系。
一、NSOperation 抽象类 NSOperation 是一个"抽象类",不能直接使用。抽象类的用处是定义子类共有的属性和方法。 NSOperation 是基于 GCD 做的面向对象的封装。 相比较 GCD 使用更加简单,并且提供了一些用 GCD 不是很好实现的功能。 苹果公司推荐使用的并发技术。 ,针对多核处理器的并发技术 在队列中执行的是由 block 构成的任务,这是一个轻量级的数据结构 要停止已经加入 queue 的 block 需要写复杂的代码 需要通过 Barrier 或者同步任务设置任务之间的依赖关系 OC 框架,更加面向对象,是对 GCD 的封装。 iOS 2.0 推出的,苹果推出 GCD 之后,对 NSOperation 的底层全部重写。 可以跨队列设置操作的依赖关系 可以设置队列中每一个操作的优先级 高级功能: 最大操作并发数(GCD不好做) 继续/暂停/全部取消 跨队列设置操作的依赖关系 四、代码实践 1 // 2 // ViewController.m
一、简介 NSOperation 的作用 NSOperation 是对 GCD 的一层封装,更加面向对象。 :(NSInteger); 5.队列的取消、暂停、恢复 取消队列的所有操作 -(void)cancelAllOperations; 注意:也可以调用 NSOperation 的 -(void)cancel ),就会自动放到子线程中执行 8.NSOperation 其他用法 操作依赖 NSOperation 之间可以设置依赖来保证执行顺序,比如,一定要让操作 A 执行后,才能执行操作 B,可以这么写 [operation addDependency:operationA]; //操作 B 依赖于操作 A 可以在不同 queue 的 NSOperation 之间创建依赖关系 ? 2016-05-06_16-58-35.png 注意:不能相互依赖,比如,A 依赖 B,B 依赖 A 操作的监听 可以监听一个操作的执行完毕 -(void (^)(void))completionBlock
即操作依赖可以控制操作的执行顺序,使多个并行的操作可以按照串行的顺序一个一个地执行。 注意:一定要在操作添加到队列之前设置操作之间的依赖,否则操作已经添加到队列中在设置依赖,依赖不会生效。 问题:默认情况下,操作队列中的操作的执行顺序真的是无序的吗? 不同队列的操作之间也可以设置依赖 依赖关系不局限于相同queue中的NSOperation对象,NSOperation对象会管理自己的依赖, 因此不同的操作队列之间的操作也可以设置依赖。 (4.)优先级不能替代依赖,优先级也绝不等于依赖。优先级只是对已经准备好的操作确定其执行顺序。 (5.)操作的执行优先满足依赖关系,然后再满足优先级。 - (void)cancelAllOperations; 队列通过调用对象方法- (void)cancelAllOperations;可以取消队列中尚未执行的操作。但是正在执行的操作不能够取消。
可以调⽤start⽅法来执⾏任务,但默认是同步执行的 如果将NSOperation添加到NSOperationQueue(操作队列)中,系统会自动异步执行NSOperation中的操作 添加操作到 那么这种情况,就可以设置在用户操作UI(如滚动屏幕)的时候,暂停队列(不是取消队列),停止滚动的时候,恢复队列。 4.操作依赖 (1)NSOperation之间可以设置依赖来保证执行顺序,⽐如一定要让操作A执行完后,才能执行操作B,可以像下面这么写 [operationB addDependency:operationA ]; // 操作B依赖于操作A (2)可以在不同queue的NSOperation之间创建依赖关系 不能循环依赖(不能A依赖于B,B又依赖于A)。 提示:任务添加的顺序并不能够决定执行顺序,执行的顺序取决于依赖。使用Operation的目的就是为了让开发人员不再关心线程。
一、NSOperation NSOperation是苹果公司对GCD的封装,完全面向对象,但是比GCD拥有更强的可控性和代码可读性。所以使用起来更好理解。 五、NSOPerationQueue NSOperationQueue就是执行NSOperation的队列,我们可以将一个或多个NSOperation对象放到队列中去执行,而且是异步执行的。 六、添加NSOperation的依赖对象 当某个NSOperation对象依赖于其它NSOperation对象的完成时,就可以通过addDependency方法添加一个或者多个依赖的对象,只有所有依赖的对象都已经完成操作 需要先添加依赖关系,再将操作添加到队列中。另外,通过removeDependency方法来删除依赖对象。 ? ps: 使用依赖关系需要注意,依赖关系不局限于相同queue中的NSOperation对象,NSOperation对象会管理自己的依赖, 因此完全可以在不同的queue之间的NSOperation对象创建依赖关系
: ① 最大并发数 ② 队列的暂停/继续/取消操作 ③ 指定操作之间的依赖关系(GCD 中可以使用同步实现) 1.3 NSOperation 与 NSOperationQueue NSOperation 创建队列:创建一个 NSOperationQueue 对象; ③ 添加操作到队列中:然后将 NSOperation 对象添加到 NSOperationQueue 队列中。 如果不想使用 NSOperationQueue,可以通过调用 NSOperation 对象的start方法来自己执行操作。 NSOperation 之间可以通过以下方法添加/移除依赖来保证执行顺序。 26:01.721032+0800 多线程[29650:6560162] 执行任务B,<NSThread: 0x6000003ed680>{number = 8, name = (null)} */ 可以在不同队列的操作之间添加依赖关系
NSOperation NSOperation类是用来封装在单个任务相关的代码和数据的抽象类。NSOperation 是苹果公司对 GCD 的封装,完全面向对象,所以使用起来更好理解。 创建队列 我们可以调用一个 NSOperation 对象的 start() 方法来启动这个任务,这个默认是 同步执行 的。 NSOperation 之间添加依赖 NSOperation 有一个非常实用的功能,那就是对任务添加依赖。 B.可以使用 removeDependency 来解除依赖关系。 C.可以在不同的队列之间依赖,依赖是添加到任务身上的,和队列没关系。 可以在轻松在Operation间设置依赖关系,而GCD需要写很多的代码才能实现 NSOperationQueue支持KVO,可以监测operation是否正在执行(isExecuted)、是否结束(isFinished
这个类是一个抽象类,通常情况下,我们会使用NSInvocationOperation和NSBlockOperation这两个子类进行多线程的开发,当然我们也可以写继承于NSOperation的类,封装我们自己的操作类 3、使用NSInvocationOperation调用方法 根据选择器创建一个对象 - (instancetype)initWithTarget:(id)target selector:(SEL)sel 二、操作之间的依赖关系 依赖关系和优先级的作用很像,却也不同。如果一个操作A依赖于另一个操作B,那么只有当B操作完成后,A操作才会执行。 *)op; 原则上说,一个操作对象的依赖可以添加多个,并且当所有依赖都执行完成后才会执行这个操作。 ; 获取主线程中的操作队列 + (NSOperationQueue *)mainQueue; 四、队列中操作的执行顺序法则 1、决定于依赖关系,只有当这个操作的依赖全部执行完成后,它才会被执行。
,它是 GCD 的面向对象的封装,使用起来也更方便, NSOperation实现多线程 NSOperation是个抽象类,并不具备封装操作的能力,必须使用它的子类 NSInvocationOperation NSBlockOperation 自定义子类继承NSOperation,实现内部相应的方法 使用 NSOperation 实现多线程的步骤: 创建任务 NSOperation 对象 创建 NSOperationQueue NSOperationQueue创建队列:主队列和全局队列 // 创建一个其他队列(包括串行队列和并发队列) 放到这个队列中的NSOperation对象会自动放到子线程中执行 NSOperationQueue ,但可以跨队列依赖,不管NSOperation对象在哪个队列。 只要是两个NSOperation对象就可以依赖 线程间通信 示例:下载图片 // 下载图片 operation实现线程间通信 [[[NSOperationQueue alloc] init] addOperation
本系列文章主要讲解iOS中多线程的使用,包括:NSThread、GCD、NSOperation以及RunLoop的使用方法详解,本系列文章不涉及基础的线程/进程、同步/异步、阻塞/非阻塞、串行/并行, 和NSOperationQueue这一面向对象的多线程类,这两个类与GCD提供的功能类似,NSOperation提供任务的封装,NSOperationQueue顾名思义,提供执行队列,可以自动实现多核并行计算 使用NSOperation和NSOperationQueue来编写多线程程序非常简单,只需要创建一个任务对象,创建一个执行队列或者和获取主线程一样获取一个主任务队列,然后将任务提交给队列即可实现并发,如过你想要串行只需要将队列的并发数设置为一即可 任务依赖关系图 如图所示,任务2依赖任务1,任务3依赖任务1,任务4依赖任务3,而任务5是独立的,所以任务2需要等待任务1完成后才可以开始执行,任务3也是同样,而任务4需要等待任务3完成后才可以开始执行 并且实现了main方法,在官方文档中指出,非并发任务,直接调用main方法即可,调用之后就和调用普通对象的方法一样,使用当前线程来执行main方法,在本栗中即主线程,这个栗子没有什么特别奇特的地方,但其实也可以将其加入到队列中
分别对比 Pthreads : 跨系统 c 语言多线程框架,不推荐。 NSThread : ## 面向对象,需手动管理生命周期。 可以使用 addDependency: 与 removeDepencency 来添加或移除依赖。 NSOperation 的依赖规则不会区分依赖操作是否真正完成(被取消也被认为完成)。不过,开发者可以决定当依赖操作被取消或未真正完成时是否继续完成这个 NSOperation。 取消一个正在等待依赖项完成的 NSOperation,这些依赖项将被忽略而直接将此属性的值更新为 YES,以表示可正常运行。此时,操作队列将更快将其移除。 如果需要控制并发数、取消任务、添加依赖关系等,那就使用 NSOperation Queue 好了。只不过很多时候都需要子类化 NSOperation。。。
如果你不想子类化NSOperation,可以选择使用NSBlockOperation这个NSOperation的子类,它可以把一个block包装成为一个NSOperation. 可以通过调用-start方法来启动一个NSOperation,或者把它放到NSOperationQueue里,当到达队列最前端时也会被自动的执行。 取消一个operation可以是显式的调用cancel方法,也可以是operation依赖的其他operation执行失败。 要记住添加到queue里的所有的operation的依赖关系,并避免循环依赖,比如A依赖B,B依赖A,这样会产生死锁。 相对于GCD非常适用于in-line的异步处理,NSOperation提供了更综合的、面向对象的计算模型,非常适用于封装结构化的数据,重复性的任务。
通过 [[NSOperationQueue alloc] init]; 创建的队列都是并行队列,并且可以将一个或多个 NSOperation 对象放到队列中去执行,而且是异步执行的,一个 NSOperation 当然也可以利用 NSOperationQueue 的线程依赖,当某个 NSOperation 对象依赖于其它 NSOperation 对象的完成时,就可以通过 addDependency 方法添加一个或者多个依赖的对象 ,只有所有依赖的对象都已经完成操作,当前 NSOperation 对象才会开始执行操作。 需要先添加依赖关系,再将操作添加到队列中。另外,通过 removeDependency 方法来删除依赖对象。 如果在某个操作依赖于其他几个任务的完成,可以考虑使用 NSOperationQueue 的线程之间依赖。
:不会开线程,任务串行执行 使用主队列(跟主线程相关联的队列) 主队列是GCD自带的一种特殊的串行队列,放在主队列中的任务,都会放到主线程中执行 //1.获得主队列 dispatch_queue_t NSOperation的使用(重点) NSOperation 是苹果公司对 GCD 的封装,完全面向对象,并比GCD多了一些更简单实用的功能,所以使用起来更加方便易于理解。 是个抽象类,并不具备封装操作的能力,必须使用它的子类 使用NSOperation子类的方式有3种 NSInvocationOperation /* 第一个参数:目标对象 第二个参数 将封装操作加入主队列 // 也可以不获取封装操作对象 直接添加操作到队列中 //[queue addOperationWithBlock:^{ // 操作 //}]; // 也可以夸队列依赖,依赖别的队列的操作 [op1 addDependency:op5]; NSOperation操作监听void (^completionBlock)(void) //
转载自:iOS多线程全套:线程生命周期,多线程的四种解决方案,线程安全问题,GCD的使用,NSOperation的使用 一、多线程的基本概念 进程:可以理解成一个运行中的应用程序,是系统进行资源分配和调度的基本单位 使用dispatch_queue_create来创建队列对象,传入两个参数,第一个参数表示队列的唯一标识符,可为空。 No.2:NSOperation的三种创建方式 NSInvocationOperation的使用:创建NSInvocationOperation对象并关联方法,之后start。 NSOperation的子类:首先我们定义一个继承自NSOperation的类,然后重写它的main方法,之后就可以使用这个子类来进行相关的操作了。 No.6:NSOperation的操作依赖 NSOperation有一个非常好用的方法,就是操作依赖。
本文重点 NSThread 多线程基础、pthread、开启线程的3种方式 线程的状态、线程安全问题、线程间的通信 GCD 同步方法和异步方法、队列的使用、线程间的通信 延迟执行、一次性代码、队列组 NSOperationQueue的常见方法、最大并发数、操作依赖、队列的取消\暂停\恢复 一、概念 1、进程:系统中正在运行的一个应用程序 2、线程:1个进程想要执行任务,必须得有线程。 根据抽象层次从低到高依次列出iOS所支持的多线程编程方法: Thread :是三种方法里面相对轻量级的,但需要管理线程的生命周期、同步、加锁问题,这会导致一定的性能开销 Cocoa Operations :是基于OC实现的,NSOperation以面向对象的方式封装了需要执行的操作,不必关心线程管理、同步等问题。 NSOperation是一个抽象基类,iOS提供了两种默认实现:NSInvocationOperation和NSBlockOperation,当然也可以自定义NSOperation.
云端获取和启用云服务器,并实时扩展或缩减云计算资源。云服务器 支持按实际使用的资源计费,可以为您节约计算成本。 腾讯云服务器(CVM)为您提供安全可靠的弹性云计算服务。只需几分钟,您就可以在云端获取和启用云服务器,并实时扩展或缩减云计算资源。云服务器 支持按实际使用的资源计费,可以为您节约计算成本。
扫码关注云+社区
领取腾讯云代金券