使用addOperationWithBlock的操作顺序

时间:2013-04-08 16:52:42

标签: ios cocoa-touch nsoperationqueue

我在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个值,因此ADDED在日志中显示4次​​。 的 BUT 下, 当我在 filterResults 中查看时,我发现 myArray 中只有 2 对象。这意味着调用了operationQueue的4次并没有在调用filterResults操作之前结束(尽管稍后添加了它!)

我认为operationQueue是串行的,我可以依赖它,当我添加一个操作时,它将在最后一次操作后立即添加。 所以奇怪的是,在后果中只有2个操作在数组中。 我错过了什么?感谢

1 个答案:

答案 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];
     }];
}];