如何检查NSOperationQueue是否完成以及是否有任何操作失败?

时间:2011-10-18 10:19:28

标签: objective-c multithreading nsoperation nsoperationqueue

我正在尝试在后台解析一些XML文件,以便UI不会冻结。我必须检查两件事:

  • NSOperationQueue结束了吗?
  • NSOperation - 解析确实失败了?

我有一个继承NSOperation的类,如果解析失败,则会调用一个委托。队列中的操作仅限于一个。

我的问题是我不能依赖在我获得队列之前执行失败消息的事实。有时候,在收到完成的消息之前,我没有收到失败的消息。然后,例如,我有这个订单:

操作1成功 操作2成功 OperationQueue完成了 操作3失败

所有消息都发送到主线程。在我收到完成的消息后,我想继续我的代码,但前提是所有操作都成功。如何处理队列完成后调用委托消息的问题。

这是我的代码的一些部分:

//XMLOperation.m
- (void)main {    
    NSLog(@"Operation started");

    if ([self parseXML]) {
            [self performSelectorOnMainThread:@selector(finishedXMLParsing) withObject:nil waitUntilDone:NO];
        } else {
            [self performSelectorOnMainThread:@selector(failedXMLParsing) withObject:nil waitUntilDone:NO];
        }
    }
    NSLog(@"Operation finished");
}


//StartController.m
[self.xmlParseQueue addObserver:self forKeyPath:@"operations" options:0 context:NULL];

...

- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object 
                         change:(NSDictionary *)change context:(void *)context
{
    if (object == self.xmlParseQueue && [keyPath isEqualToString:@"operations"]) {
        if ([self.xmlParseQueue.operations count] == 0) {
            // Do something here when your queue has completed
            NSLog(@"queue has completed");
        }
    }
    else {
        [super observeValueForKeyPath:keyPath ofObject:object 
                               change:change context:context];
    }
}

1 个答案:

答案 0 :(得分:2)

这可能是因为您的完成/失败通知所在的主线程上未必传递队列的operations属性的KVO通知。

您应该确保在主线程上执行完成通知,以便定义通知的顺序。