我有一个NSOperation
,我要同时运行的子类。
我的理解是,对并发操作的工作:
- 我需要定义
isConcurrent
返回YES
。 - 我需要定义
start
方法 - 我需要发送KVOs通知
isExecuting
和isFinished
当它这样做。 - 使用
@synthesize
当值会自动发出相应的志愿通知isExecuting
和isFinished
改变。
尽管这样,我已经验证了我的队列从来没有移动到下一个项目。
这里是我的代码的肉:
@interface MyOperation()
@property (readwrite) BOOL isExecuting;
@property (readwrite) BOOL isFinished;
@end
@implementation MyOperation
- (void)start
{
@autoreleasepool {
self.isExecuting = YES;
self.HTTPOperation = [[AFHTTPRequestOperation alloc] initWithRequest: URLRequest];
_HTTPOperation.completionBlock = [^{
[self completed];
self.isExecuting = NO;
self.isFinished = YES;
} copy];
[_HTTPOperation start];
}
}
- (BOOL)isConcurrent
{
return YES;
}
- (void)completed
{
}
@end
我在想什么?
(这是在iPhone上,但我无法想象的问题。)
它看起来像任何志愿通知@synthesize
将是不够的NSOperationQueue
继续前进。
发送手动通知解决了这个问题:
- (void)start
{
@autoreleasepool {
[self willChangeValueForKey:@"isExecuting"];
self.isExecuting = YES;
[self didChangeValueForKey:@"isExecuting"];
NSURLRequest *URLRequest = [self buildRequest];
if (!URLRequest) {
[self willChangeValueForKey:@"isFinished"];
[self willChangeValueForKey:@"isExecuting"];
_isExecuting = NO;
_isFinished = YES;
[self didChangeValueForKey:@"isExecuting"];
[self didChangeValueForKey:@"isFinished"];
return;
}
self.HTTPOperation = [[AFHTTPRequestOperation alloc] initWithRequest: URLRequest];
_HTTPOperation.completionBlock = [^{
[self completed];
[self willChangeValueForKey:@"isFinished"];
[self willChangeValueForKey:@"isExecuting"];
_isExecuting = NO;
_isFinished = YES;
[self didChangeValueForKey:@"isExecuting"];
[self didChangeValueForKey:@"isFinished"];
} copy];
[_HTTPOperation start];
}
}
也可以看看:
- 为什么的NSOperation禁用自动键-值观察?
What's your "queue" look like? Are you using an NSOperationQueue?
Anyway, I'll try to answer your question with what I understood :P
I would create a delegate for my NSOperation and have KVO take care of calling this.
Say for example your NSOperation class looks like this
@interface MyOperation : NSOperation
@property (assign) id<MyOperationDelegate> delegate;
Your implementation
@synthesize delegate;
@synthesize error;
-(id)init{
self = [super init];
if(self){
[self addObserver:self forKeyPath:@"isFinished"
options:NSKeyValueObservingOptionNew
context:NULL];
}
return self;
}
-(void)dealloc{
[self removeObserver:self forKeyPath:@"isFinished"];
[super dealloc];
}
-(void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
if([keyPath isEqualToString:@"isFinished"] == YES){
if([self isCancelled] == NO){
if(delegate != nil && [delegate respondsToSelector:@selector(operationComplete:)]){
[delegate taskComplete:self];
}
}else{
if(delegate != nil && [delegate respondsToSelector:@selector(operationCancelled)]){
[delegate taskCancelled];
}
}
}
}
-(void)main{
[NSException exceptionWithName:kTaskException
reason:@"Only to be used with subclass"
userInfo:nil];
}
And finally your protocol
@class MyOperation;
@protocol MyOperationDelegate <NSObject>
@optional
-(void)operationComplete:(MyOperation*)operation;
-(void)operationCancelled;