+++
Categories = ["iOS",]
Tags = ["iOS","NSOperation"]
date = "2014-11-17T14:01:09+08:00"
title = "多线程 NSOperation"
+++
NSOperation介绍
NSOperation是一个抽象的基类,表示一个独立的计算单元,可以为子类提供有用且线程安全的建立状态,优先级,依赖和取消等操作。系统已经给我们封装了NSBlockOperation和NSInvocationOperation这两个实体类。
- 使用NSOperation处理多线程时,就是将“操作”添加到队列中。
- NSOperation是一个抽象类,不能直接使用(方法没有实现),约束子类都具有共同的属性和方法。
- NSOperation的子类:NSInvocationOperation、NSBlockOperation、自定义NSOperation。
- 通过NSOperationQueue可以创建并发队列,获取主队列,获取当前队列。
NSOperation定义
- (void)start;
- (void)main;
@property (readonly, getter=isCancelled) BOOL cancelled;
- (void)cancel;
@property (readonly, getter=isExecuting) BOOL executing;
@property (readonly, getter=isFinished) BOOL finished;
@property (readonly, getter=isConcurrent) BOOL concurrent; // To be deprecated; use and override 'asynchronous' below
@property (readonly, getter=isAsynchronous) BOOL asynchronous NS_AVAILABLE(10_8, 7_0);
@property (readonly, getter=isReady) BOOL ready;
- (void)addDependency:(NSOperation *)op;
- (void)removeDependency:(NSOperation *)op;
@property (readonly, copy) NSArray *dependencies;
typedef NS_ENUM(NSInteger, NSOperationQueuePriority) {
NSOperationQueuePriorityVeryLow = -8L,
NSOperationQueuePriorityLow = -4L,
NSOperationQueuePriorityNormal = 0,
NSOperationQueuePriorityHigh = 4,
NSOperationQueuePriorityVeryHigh = 8
};
@property NSOperationQueuePriority queuePriority;
@property (copy) void (^completionBlock)(void) NS_AVAILABLE(10_6, 4_0);
- (void)waitUntilFinished NS_AVAILABLE(10_6, 4_0);
@property double threadPriority NS_DEPRECATED(10_6, 10_10, 4_0, 8_0);
@property NSQualityOfService qualityOfService NS_AVAILABLE(10_10, 8_0);
@property (copy) NSString *name NS_AVAILABLE(10_10, 8_0);
状态
NSOperation提供了ready cancelled executing finished
这几个状态变化,我们的开发也是必须处理自己关心的其中的状态。这些状态都是基于keypath的KVO通知决定,所以在你手动改变自己关心的状态时,请别忘了手动发送通知。这里面每个属性都是相互独立的,同时只可能有一个状态是YES。finished这个状态在操作完成后请及时设置为YES,因为NSOperationQueue所管理的队列中,只有isFinished为YES时才将其移除队列,这点在内存管理和避免死锁很关键。
依赖
NSOperation中我们可以为操作分解为若干个小的任务,通过添加他们之间的依赖关系进行操作,我们可以直接调用 - (void)addDependency:(NSOperation*)op;
这个方法添加依赖.依赖关系可以跨操作队列,操作不再同一个队列中,依赖关系也是存在的。
执行
执行一个operation有两种方法,第一种是自己手动的调用start这个方法,这种方法调用会在当前调用的线程进行同步执行,所以在主线程里面自己一定要小心的调用,不然就会把主线程给卡死。第二种是将operation添加到operationQueue中去,这个也是我们用得最多的也是提倡的方法。NSOperationQueue会在我们添加进去operation的时候尽快进行执行。当然如果 NSOperationQueue的maxConcurrentOperationCount
如果设置为1的话,进相当于FIFO了。
GCD和NSOperation的对比
- GCD
GCD是iOS4.0推出的,主要针对多核CPU做了优化,是C语言的技术。
GCD是将任务(block)添加到队列(串行/并行/全局/主队列),并且以同步/异步的方式执行任务的函数。
GCD提供给了一些NSOperation不具备的功能:①一次性执行;②延迟执行;③调度组。
- NSOperation
NSOperation是iOS2.0推出的,iOS4.0之后重写了NSOperation。
NSOperation将操作(异步的任务)添加到队列(并发队列),就会执行指定操作的函数。
NSOperation里提供的方便的操作:①最大并发数;②队列的暂停/继续;③取消所有的操作;④指定操作之间的依赖关系(GCD可以用同步实现)。
网友评论