2013-08-02 11 views
7

ho fatto la seguente classe di test per provare il recupero dei dati da Parse:findObjectsInBackgroundWithBlock: ottiene i dati da analizzare, ma i dati esiste solo all'interno del blocco

-(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... 
} 

Per la sezione commentata all'interno del codice, quando stampo self.scoreDictionary all'interno del codice, funziona bene, e vedo il mio intero dizionario man mano che viene riempito in modo incrementale. Tuttavia, al termine del blocco, quando stampo di nuovo il dizionario, ora è vuoto. Ho controllato due volte con i documenti API della query, ma non sono ancora sicuro di cosa sto facendo in modo errato.

risposta

13

L'ultima istruzione NSLog(@"The dictionary is %@", self.scoreDictionary) non viene effettivamente eseguita dopo il completamento del blocco. Esegue dopo i ritorni del metodo findObjectsInBackgroundWithBlock. findObjectsInBackgroundWithBlock probabilmente esegue qualcosa in un thread separato e il blocco potrebbe non essere eseguito affatto fino a un certo lasso di tempo dopo l'ultima istruzione NSLog. Graficamente, qualcosa di simile a questo è probabilmente accadendo:

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 

Probabilmente si desidera pensare, cosa vuoi fare con i tuoi dati scoreDictionary dopo aver recuperato lo? Ad esempio, vuoi aggiornare l'interfaccia utente, chiamare qualche altro metodo, ecc.? Dovrai fare questo all'interno del tuo blocco, a quel punto saprai che i dati sono stati recuperati con successo. Ad esempio, se si ha una vista tabella si voleva ricaricare, si potrebbe fare questo:

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

Annotare il dispatch_async - se il lavoro è necessario fare dopo l'aggiornamento dei dati comporta la modifica l'interfaccia utente, ti consigliamo quello da eseguire sul thread principale.

+0

Grazie, soprattutto per l'illustrazione molto utile che mostra i fili! – daspianist

Problemi correlati