2011-10-18 52 views
1

我想解析背景中的一些XML文件,以便UI不冻结。我必须检查两件事:如何检查NSOperationQueue是否完成,如果有任何操作失败?

  • 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]; 
    } 
} 
+0

为2017年1月时,苹果文档中提到,您可以访问 “operationCount”。只需在需要时检查。 https://developer.apple.com/reference/foundation/nsoperationqueue?language=objc –

回答

1

这可能是因为队列的operations财产的志愿通知的不一定是主线程上发表,同时已完成/失败的通知的。

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

+0

也许这是一个愚蠢的问题,但我该怎么做? – MoFuRo

+0

与在主操作的'main'方法中执行操作的方式相同,执行在主线程上完成队列时执行的操作。 – omz

+0

我已验证KVO解决方案,并且失败,当最后一个操作将被执行但尚未执行时,操作队列的操作数组已将其删除,因此它不起作用。 – Itachi

0

恢复此问题并在此处粘贴我的代码解决方案。

void RunInMainThread(void (^block)(void)) 
{ 
    if (!block) { 
     return; 
    } 

    if ([NSThread isMainThread]) { 
     block(); 
    } else { 
     dispatch_async(dispatch_get_main_queue(), block); 
    } 
} 

@interface MyOperationQueue : NSOperationQueue 

@property (nonatomic, assign) NSUInteger totalCount; 
@property (nonatomic, copy) dispatch_block_t allOperationCompletionBlock; 

@end 

@implementation MyOperationQueue 

- (void)addOperation:(NSOperation *)op 
{ 
    [super addOperation:op]; 
    __weak typeof(self) weakSelf = self; 

    self.totalCount++; 
    DDLogVerbose(@"Added a operation, total: %ld operation(s).", self.totalCount); 

    op.completionBlock =^{ 
     weakSelf.totalCount--; 
     DDLogVerbose(@"Finished a operation, left: %ld operation(s).", weakSelf.totalCount); 

     if (weakSelf.totalCount == 0) { 
      if (weakSelf.allOperationCompletionBlock) { 
       RunInMainThread(weakSelf.allOperationCompletionBlock); 
      } 
     } 
    }; 
} 

@end

相关问题