findObjectsInBackgroundWithBlock: obtiene datos de Parse, pero los datos solo existen dentro del bloque

Hice la siguiente clase de prueba para intentar recuperar datos de Parse:

-(void)retrieveDataFromParse { PFQuery *query = [PFQuery queryWithClassName:@"TestObject"]; [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) { if(!error){ for (PFObject *object in objects){ NSString *nameFromObject = [NSString stringWithFormat:@"%@", [object objectForKey:@"Name"]]; NSString *dateFromObject = [NSString stringWithFormat:@"%@", [object createdAt]]; NSString *scoreFromObject = [NSString stringWithFormat:@"%@", [object objectForKey:@"Score"]]; [self addNewScore:scoreFromObject andDate:dateFromObject forUserName:nameFromObject]; NSLog(@"The dictionary is %@", self.scoreDictionary); //<-- here it works printing out the whole dictionary } } else { NSLog(@"Error: %@ %@", error, [error userInfo]); } }]; NSLog(@"The dictionary is %@", self.scoreDictionary); //<- but after the block is called, here the dictionary is again empty... } 

Según la sección comentada dentro del código, cuando self.scoreDictionary dentro del código, funciona bien, y veo todo el diccionario a medida que se llena de forma incremental. Sin embargo, después de que termina el bloque, cuando imprimo el diccionario nuevamente, ahora está vacío. Comprobé dos veces con los documentos API de consulta, pero todavía no estoy seguro de lo que estoy haciendo de manera incorrecta.

La última NSLog(@"The dictionary is %@", self.scoreDictionary) realidad no se ejecuta una vez que se completa el bloque. Se ejecuta después de que el método findObjectsInBackgroundWithBlock regrese. findObjectsInBackgroundWithBlock presumiblemente ejecuta algo en un subproceso separado, y es posible que su bloque no se ejecute en realidad hasta algún tiempo después de esa última instrucción NSLog. Gráficamente, probablemente esté sucediendo algo como esto:

 Thread 1 -------- retriveDataFromParse called invoke findObjectsInBackgroundWithBlock findObjectsInBackgroundWithBlock queues up work on another thread findObjectsInBackgroundWithBlock returns immediately | NSLog statement - self.scoreDictionary not yet updated | retriveDataFromParse returns | . V . Thread 2, starting X milliseconds later . -------- . findObjectsInBackgroundWithBlock does some work . your block is called . for-loop in your block . Now self.scoreDictionary has some data . NSLog statement inside your block 

Probablemente desee pensar, ¿qué desea hacer con su información ScoreDictionary después de haberla recuperado ? Por ejemplo, ¿desea actualizar la interfaz de usuario, llamar a algún otro método, etc.? Deberá hacer esto dentro de su bloque, en ese momento sabrá que los datos se han recuperado con éxito. Por ejemplo, si tiene una vista de tabla que desea volver a cargar, puede hacer esto:

 for (PFObject *object in objects){ .... } dispatch_async(dispatch_get_main_queue(), ^{ [self updateMyUserInterfaceOrSomething]; }); 

Tenga en cuenta el dispatch_async : si el trabajo que necesita hacer después de actualizar sus datos implica cambiar la interfaz de usuario, querrá que se ejecute en el hilo principal.

El último NSLog(@"The dictionary is %@", self.scoreDictionary) se ejecuta antes de que se ejecute el bloque de finalización. Por el momento, self.scoreDictionary estará vacío de seguro.

Además, el bloque de finalización se ejecutará en el hilo principal. Puede consultar el siguiente enlace.

https://parse.com/questions/what-thread-does-findobjectsinbackgroundwithblock-complete-on