An operation object is an instance of the NSOperation class (in the Foundation framework) that you use to encapsulate work you want your application to perform. The NSOperation class itself is an abstract base class that must be subclassed in order to do any useful work.
NSOperation本身是一個抽象基類,如果要使用的時候應(yīng)該先繼承它而不能直接去實例化一個NSOperation娜搂。
Foundation framework提供兩個子類贿讹,NSInvocationOperation和NSBlockOperation苛坚。NSInvocationOperation不需要再繼承才能使用,可以方便我們以現(xiàn)有的方法來初始化一個operation。NSBlockOperation方便我們通過block初始化operation。
NSOperation特征:
NSOperation之間可以建立依賴關(guān)系
可以改變operation的優(yōu)先級
能夠通過取消操作停止operation
有可選的operation block,當主任務(wù)完成后
KVO監(jiān)聽狀態(tài)
NSInvocationOperation & NSBlockOperation例子
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.operation = [self taskWithData:@"just test"];
[self.operation start];
NSBlockOperation *blockTest = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"block is comeing");
}];
[blockTest addExecutionBlock:^{
NSLog(@"blocke 2 is coming");
}];
[blockTest addExecutionBlock:^{
NSLog(@"blocke 3 is coming");
}];
[blockTest start];}
- (NSOperation *)taskWithData:(id)data{
NSInvocationOperation *invoTest = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(handleData:) object:data];
return invoTest;
}
- (void)handleData:(id) data
{
NSLog(@"my data");
NSLog(@"%@", data);
}
自定義的NSOperation
至少要實現(xiàn)兩個方法:
- A custom initialization method(初始化的方法)
- main
簡單實現(xiàn)代碼:
@implementation MyOperation
- (instancetype)initWithData:(id) data
{
if (self = [super init]) {
self.myData = data;
[self completeOperation];
}
return self;
}
- (void)main
{
@try {
NSLog(@"my operation is coming");
NSLog(@"%@", _myData);
}
@catch (NSException *exception) {
NSLog(@"%@", exception);
}
@finally {
NSLog(@"finally");
}
}
@end
在ViewController里面實例化
MyOperation *myOperation = [[MyOperation alloc] initWithData:@"my opeation"];
[myOperation start];
并發(fā)的NSOperation需要實現(xiàn)以下方法:
- (BOOL)isConcurrent
{
return YES;
}
- (BOOL)isExecuting {
return executing;
}
- (BOOL)isFinished {
return finished;
}
- (void)start{
if([self isCancelled])
{
[self willChangeValueForKey:@"isFinished"];
finished = YES;
[self didChangeValueForKey:@"isFinished"];
return;
}
[self willChangeValueForKey:@"isExecuting"];
[NSThread detachNewThreadSelector:@selector(main) toTarget:self withObject:nil];
executing = YES;
[self didChangeValueForKey:@"isExecuting"];
}
- (void)completeOperation {
[self willChangeValueForKey:@"isFinished"];
[self willChangeValueForKey:@"isExecuting"];
executing = NO;
finished = YES;
[self didChangeValueForKey:@"isExecuting"];
[self didChangeValueForKey:@"isFinished"];
}
Operation中支持KVO的屬性
isCancelled
isConcurrent
isExecuting
isFinished
isReady
dependencies
queuePriority
completionBlock
NSOperationQueue
兩種初始化的方法:
NSOperationQueue *myQueue1 = [[NSOperationQueue alloc] init];
NSOperationQueue *myQueue2 = [NSOperationQueue mainQueue];//mainQueue
[myQueue1 addOperation:myOperation];
[myQueue1 addOperation:self.operation];
[myQueue1 addOperation:blockTest];
- NSOperationQueue有優(yōu)先級的概念粥喜,因此是不支持FIFO的
- NSOperationQueue是并發(fā)執(zhí)行的,但是可以通過maxConcurrentOperationCount來設(shè)置并發(fā)的數(shù)量
NSOperation相對于GCD的優(yōu)勢
可以取消某個操作橘券。調(diào)用cancel方法可以取消操作,但是開始的任務(wù)是無法取消的额湘。而GCD是fire and forget模式。
指定操作間的依賴關(guān)系旁舰,指定特定的任務(wù)必須在某個任務(wù)完成后執(zhí)行锋华。
可以通過KVO監(jiān)控NSOperation對象的屬性。通過KVO就可以在何時結(jié)束何時掛起獲得通知鬓梅,進而做一些處理
指定操作間的優(yōu)先級供置。GCD的優(yōu)先級是針對整個隊列來說的,操作隊列就能比較方便的實現(xiàn)優(yōu)先級操作
重用NSOperation對象绽快。
參考
- 《Effective Objective-C 2.0》
- 《Concurrency Programming Guide》