2013-04-08 27 views
3

我面臨addOperationWithBlock的一些奇怪的結果。使用addOperationWithBlock的操作順序

我的功能看起來是這樣的:

-(void) myFunction{ 
    NSLog(@"VISITED"); 

.. 



    for (NSDictionary *Obj in myObjects) 
    { 
    [operationQueue addOperationWithBlock:^(void){ 
     MyObject* tmp = [self tediousFunction:Obj]; 
     // threadTempObjects is member NSMutableArray 
     [self.threadTempObjects addObject:tmp]; 
     NSLog(@"ADDED"); 
    }]; 
    } 

[operationQueue addOperationWithBlock:^(void){ 
     [self.myArray addObjectsFromArray:self.threadTempObjects]; 

     for(myObject *myObj in self.myArray) 
     { 
      // MAIN_QUEUE 
      [[NSOperationQueue mainQueue] addOperationWithBlock:^(void) { 
       [self updateUI:myObj]; 
      }]; 
     } 
    }]; 



    [operationQueue addOperationWithBlock:^(void){ 
     [[NSOperationQueue mainQueue] addOperationWithBlock:^(void) { 
      [self filterResults]; 
     }]; 
    }]; 

} 

我的字典有4個值,因此增加的顯示在日誌中的4倍。 , 當我檢查filterResults裏面,我看到有隻內myArray的對象。這意味着調用operationQueue的4倍並沒有在調用filterResults操作之前結束(儘管它稍後添加了!)

我認爲operationQueue是串行的,我可以指望當我添加操作它會在最後一次操作後立即添加。 所以奇怪的是,後果只有2個操作在數組中。 我錯過了什麼?謝謝

+1

您正在使用這裏有2個不同的隊列,請分享他們的配置代碼,以便我們驗證他們確實是串行的(串行意味着maxConcurrentOperationCount爲1) –

+0

您可能會對[GCD操作隊列](http://developer.apple.com/庫/ IOS /#文檔/ G ENERAL /概念/ ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html)。 –

+0

您的操作隊列只有在串行時纔是串行的。 –

回答

3

從你作爲初始化代碼共享的內容可知,operationQueue不是串行的,意味着它將執行操作並分配線程,直到系統設置最大線程數(與GCD相同)。
這意味着添加到operationQueue的操作並行運行。
要運行它們串聯設置maxConcurrentOperationCount爲1
試着這麼做:

__block __weak id weakSelf = self; 
[operationQueue setMaxConcurrentOperationCount:1]; 

for (NSDictionary *Obj in myObjects) 
{ 
    [operationQueue addOperationWithBlock:^{ 
     MyObject* tmp = [weakSelf tediousFunction:Obj]; 
     // threadTempObjects is member NSMutableArray 
     [weakSelf.threadTempObjects addObject:tmp]; 
     NSLog(@"ADDED"); 
    }]; 
} 

[operationQueue addOperationWithBlock:^{ 
    [weakSelf.myArray addObjectsFromArray:weakSelf.threadTempObjects]; 

    for(myObject *myObj in weakSelf.myArray) 
    { 
     // MAIN_QUEUE 
     [[NSOperationQueue mainQueue] addOperationWithBlock:^(void) { 
      [weakSelf updateUI:myObj]; 
     }]; 
     [[NSOperationQueue mainQueue] addOperationWithBlock:^(void) { 
      [weakSelf filterResults]; 
     }]; 
    } 
}]; 

但是,這是等於(或效率更低)簡單:

__block __weak id weakSelf = self; 
[operationQueue addOperationWithBlock:^{ 
    for (NSDictionary *Obj in myObjects) { 
     MyObject* tmp = [weakSelf tediousFunction:Obj]; 
     // threadTempObjects is member NSMutableArray 
     [[NSOperationQueue mainQueue] addOperationWithBlock:^(void) { 
      [weakSelf updateUI:tmp]; 
     }]; 
     [weakSelf.myArray addObject:tmp]; 
     NSLog(@"ADDED"); 
    } 
    [[NSOperationQueue mainQueue] addOperationWithBlock:^(void) { 
     [weakSelf filterResults]; 
    }]; 
}]; 
+0

嗨丹,在你的第一個例子中,你這樣做:'operationQueue addOperationWithBlock'。如果在這個模塊中我們還會有:'operationQueue addOperationWithBlock'(new addOperationWithBlock block),可以嗎?我找不到有關這方面的信息。或者最好避免它,只是刪除第二個操作塊? –

+1

@flinth這應該也適用於嵌套'addOperationWithBlock' –