2010-07-04 54 views
0

我有一些iPhone SDK 4.0代碼初始化NSOperationQueue,然後添加三個類(ClassA,ClassBClassC)一個接一個地運行。 ClassA,ClassBClassC都是NSOperation的子類。從NSOperation內取消NSOperationQueue

相關代碼包含在下面。

ClassA *classA = [[ClassA alloc] init]; 
ClassB *classB = [[ClassB alloc] init]; 
ClassC *classC = [[ClassC alloc] init]; 

[classB addDependency:classA]; 
[classC addDependency:classB]; 

NSOperationQueue *queue = [[NSOperationQueue alloc] init]; 

[queue addOperation:classA]; 
[queue addOperation:classB]; 
[queue addOperation:classC]; 

[classA release]; 
[classB release]; 
[classC release]; 
[queue release]; 

的原因依賴是因爲如果classA成功地完成其操作classB應該只運行。同樣,classC只應在classB成功完成時運行。

目前我很難弄清楚如何防止,例如,如果classA未成功完成,classB就不會運行。繼續這個例子,我在想從classA以某種方式喚起[NSOperationQueue cancelAllOperations],但我不知道如何從classA(這是一個NSOperation子類)處理父NSOperationQueue。這只是我最初的想法,所以我會接受任何其他更好的建議來實現相同的結果!

每個類中都有條件代碼,用於確定它們是否已正確完成 - 目前它們只是NSLogging「Success」或「Fail」以用於調試目的。在一個完美的世界中,我只希望能夠用一些代碼來替代每個類中的NSLog(@"Fail")語句,這些代碼將停止運行NSOperationQueue中的所有其他類。

任何建議將是最受歡迎的(和讚賞)。

+0

你是什麼意思「未成功完成」。操作是否遇到錯誤或操作未完成? – falconcreek 2010-07-05 03:57:25

回答

3

你可以在CLASSA設置屬性:

@property (readonly) BOOL completedSucessfully; 

,並在CLASSA的主要方法結束這個設置爲YES。

然後,在classB的開始處檢查它。

- (void)main { 
    if (NO == [[dependencies objectAtIndex:0] completedSucessfully]) 
     return; 

現在,如果classA報告失敗,classB將停止。

NB你可能會需要更多的錯誤檢查,在上面即例如確保您有依賴性,檢查它的正確類等

- (void)main { 
    for (id *temp in [self dependencies]) 
     if ([temp isKindOfClass:[ClassA class]]) 
      if (NO == [(ClassA *)temp finishedSucessfully]) 
       return; 
+0

謝謝院長。正是我需要:) – Skoota 2010-07-06 10:42:22

+0

這種設計有問題。 [dependencies objectAtIndex:0]可能爲零。 – falconcreek 2010-07-06 15:05:52

+0

閱讀第二個代碼片段;)第一個被包含在內,以便快速閱讀,第二個是我實際使用的。 – deanWombourne 2010-07-06 15:14:50

1

我建議,如果速度不是問題,你可以同步工作。否則您可以使用:

[selector:@selctor(StartB) waitUntilTaskComplete:YES]; 
1

在查看關於高級NSOperation技術的WWDC 2015會話(強烈推薦)之後,我開始在自己的代碼中深入使用它們。這裏有一些建議,以實現這一

  1. 從內部的NSOperation你可以調用[自我currentQueue]讓「啓動該操作或零如果隊列無法確定操作隊列中。」然後您可以在返回的隊列上調用cancelAllOperations。在經驗上我很難使用這種方法,因爲如果你明確地在主隊列上運行代碼,在閉包/塊中使用代碼,或者調用第三方庫,那麼返回的隊列可能根本就不是初始隊列。在這種情況下,調用cancelAllOperations不會導致預期的行爲 - 取而代之的是取消不同隊列上的操作。

  2. 子類NSOperation包含用於初始NSOperationQueue的屬性和NSOperationQueue的子類,以在操作添加到隊列時設置屬性。然後在self.initialQueue上調用cancelAllOperations。這是我使用的方法,適用於上述所有場景。

  3. 取消取消隊列級別的所有操作,可以調用操作「取消」方法並完成操作。如果您的操作符合Apple的操作指南,則它們在啓動時都會檢查isCancelled,如果爲true,則會中止處理。這是一個細微的差別:當您取消隊列操作時,任何尚未啓動的操作都不會啓動。當您將操作設置爲isCancelled時,隨後的操作即會開始,但(應該)會在那之後很快完成。這允許以後的操作可能執行一些清理,錯誤處理或用戶通知的情況。

+0

'self.currentQueue'不是NSOperation的屬性? – peterp 2015-10-27 17:07:23

+0

這是需要的,因爲「初始」隊列和「當前」隊列之間存在差異。如果您有一個調用第三方庫的操作,或者在閉包/塊中運行代碼,那麼該代碼實際上可能在最初的一個隊列中執行。至少,這是我的經驗(尤其是Facebook SDK)。 – 2015-10-27 18:14:16

相關問題