2011-10-18 50 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

相關問題