FindObjectsInBackgroundWithBlock: gets data from Parse, but data exists only inside the block

I did the following test class to try extracting data from 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... } 

In the commented section inside the code, when I type self.scoreDictionary inside the code, it works fine, and I see the whole dictionary as it gradually fills. However, after completing the block, when I print the dictionary again, it is now empty. I double-checked the docs of the request APIs, but I'm still not sure what I'm doing wrong.

+7
asynchronous ios objective-c
source share
2 answers

The last NSLog(@"The dictionary is %@", self.scoreDictionary) statement NSLog(@"The dictionary is %@", self.scoreDictionary) does not actually execute after the block completes. It is executed after the findObjectsInBackgroundWithBlock method findObjectsInBackgroundWithBlock . findObjectsInBackgroundWithBlock supposedly starts something in a separate thread, and your block may actually not run at all until some time after this last NSLog statement. Graphically, something like this could happen:

 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 

You should probably think about what you want to do with your scoreDictionary data after you receive it ? For example, do you want to update the user interface, call another method, etc.? You will want to do this inside your block, after which you know that the data has been successfully retrieved. For example, if you had a table view that you wanted to reload, you could do this:

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

Pay attention to dispatch_async - if the work that you need to do after updating your data is related to changing the user interface, you want this to be done in the main thread.

+13
source share

The last NSLog(@"The dictionary is %@", self.scoreDictionary) is executed before the completion block is executed. By then, self.scoreDictionary will be empty.

In addition, the completion block will be executed in the main thread. You can refer to the following link.

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

0
source share

All Articles