默认方式下,operations对象习惯性的异步执行,执行操作在一个线程中由start方法唤起,因为operation queue 为非并发的operationS提供线程,尽管许多operation还是异步执行。
然而如果你计划手动操作operations同时也希望他们仍然异步执行,你必须适当的执行一些操作确保他们可以运行。你这样做的效果是使你的operation对象并发运行。这时需要按照下面的法方进行重写操作。
NSOpertaion 的子类可以选择2中执行方式
1:non-concurrent 非并发的 ,可以限制并发数
这种方式是将NSOpertaion的子类添加到NSOpertaionQuene中,并且重写NSOpertaion的main函数即可,(执行顺序为添加顺序)
2: concurrent 并发的
重写下面的方法
• start
- isConcurrent
- isExecuting
- isFinished
同时注意键值变化,必须保证是线程安全的
在这种并发的操作中,start消息用于启动这次异步操作,在这个消息中需要通过KVO 报告executing 状态(YES),这可以让感兴趣的操作端知道这个操作在执行中,同时注意该值的线程安全
一旦完成或者取消这次operation,必须通过KVO通知executing(NO)finished(YES)
状态,在取消状态中报告finished(YES)也是必须的,即使这次操作没有全部完成,如果在queue中,必须在删除操作之前报告状态的改变
NSInvocationOperation使用这个类,可以避免在程序中为了每一个任务去创建大量的operation.其实这个类就是子类化了NSOperation,同时他需要添加到NSOperationQueue中,否则他不会自动异步执行。如果你手动start,则他是堵塞进程的,(因为你可能没有重载isexecuting 等函数)。
@interface MyOperation : NSOperation {
BOOL executing;
BOOL finished;
}
- (void)completeOperation;
@end
@implementation MyOperation
- (id)init {
self = [super init];
if (self) {
executing = NO;
finished = NO;
}
return self;
}
- (BOOL)isConcurrent {
return YES;
}
- (BOOL)isExecuting {
return executing;
}
- (BOOL)isFinished {
return finished;
}
@end
- (void)start {
// Always check for cancellation before launching the task.
if ([self isCancelled])
{
// Must move the operation to the finished state if it is canceled.
[self willChangeValueForKey:@"isFinished"];
finished = YES;
[self didChangeValueForKey:@"isFinished"];
return;
}
// If the operation is not canceled, begin executing the task.
[self willChangeValueForKey:@"isExecuting"];
[NSThread detachNewThreadSelector:@selector(main) toTarget:self withObject:nil];
executing = YES;
[self didChangeValueForKey:@"isExecuting"];
}
- (void)main {
@try {
// Do the main work of the operation here.
[self completeOperation];
}
@catch(...) {
// Do not rethrow exceptions.
}
}
- (void)completeOperation {
[self willChangeValueForKey:@"isFinished"];
[self willChangeValueForKey:@"isExecuting"];
executing = NO;
finished = YES;
[self didChangeValueForKey:@"isExecuting"];
[self didChangeValueForKey:@"isFinished"];
}
重写这些方法时在任何核实后都不需要调用super
the main method is the entry point for a new thread.
main方法是新线程的入口点,在main中完成同步操作,如果main中需要执行一步操作,则需要注意main的提前结束,需要同步main函数才行。
isConcurrent 表示是否并发操作,返回YES表示并发。