order de las operaciones con addOperationWithBlock

Estoy enfrentando algunos resultados extraños con addOperationWithBlock .

Mi function se ve así:

 -(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]; }]; }]; } 

Mi dictionary contiene 4 valores y, por lo tanto, ADDED se muestra en el logging 4 veces. PERO , cuando reviso dentro de filterResults , veo que hay solo 2 objects dentro de myArray . Lo que significa que las 4 veces que se llamaba operationQueue no terminaron antes de llamar a la operación filterResults (¡aunque se agregó más tarde!)

Pensé que the operationQueue es serial y que puedo contar con que cuando agregue una operación se agregará inmediatamente después de la última operación. Por lo tanto, es raro que solo 2 operaciones se encuentren en la matriz después de esto. ¿Qué me estoy perdiendo? Gracias

De lo que compartió como su código de initialization podemos aprender que operationQueue no es serial, lo que significa que ejecutará operaciones y asignará subprocesss hasta que el sistema establezca un recuento máximo de subprocesss (igual que con GCD).
Esto significa que las operaciones agregadas a operationQueue se ejecutan en paralelo.
Para ejecutarlos en serie, establezca maxConcurrentOperationCount en 1.
Prueba algo como:

 __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]; }]; } }]; 

Pero, esto es igual (o incluso less eficiente) a simplemente:

 __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]; }]; }];