我有一个NSOperation
子类,我想同时运行。
我的理解是,要使并发操作起作用:
isConcurrent
才能返回YES
。start
方法isExecuting
和isFinished
完成后发送KVO通知。@synthesize
和isExecuting
的值发生变化时,使用isFinished
会自动发送相应的KVO通知。尽管如此,我已经确认我的队列永远不会移动到下一个项目。
以下是我的代码的内容:
@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上,但我无法想象这很重要。)
答案 0 :(得分:4)
看起来任何KVO通知@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];
}
}
另见:
答案 1 :(得分:1)
你的“队列”是什么样的?你在使用NSOperationQueue吗?
无论如何,我会尝试用我理解的方式回答你的问题:P
我会为我的NSOperation创建一个委托,让 KVO 负责调用它。
例如,您的 NSOperation 类看起来像这样
@interface MyOperation : NSOperation
@property (assign) id<MyOperationDelegate> delegate;
您的实施
@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];
}
最后你的协议
@class MyOperation;
@protocol MyOperationDelegate <NSObject>
@optional
-(void)operationComplete:(MyOperation*)operation;
-(void)operationCancelled;