1

I want to save PFObjects from a Parse query in an NSMutableArray that my class has called listdata. I will later use the listdata array. When I traced through my code, it updated the highScoreObjects array for each object found. But when I try to set the listdata array to the highScoreObjects array, the highScoreObjects array is empty. Is there a way to keep the data after the query ends?

NSMutableArray *highScoreObjects = [[NSMutableArray alloc] initWithCapacity:5];

    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
        if (!error) {
            // The find succeeded.
            NSLog(@"Successfully retrieved %d scores.", objects.count);
            // Do something with the found objects
            for (PFObject *object in objects) {
                [highScoreObjects addObject:object];
                NSLog(@"%@", object.objectId);
            }
            dispatch_async(dispatch_get_main_queue(), ^ {
                [self.tableView reloadData];
            });
        } else {
            // Log details of the failure
            NSLog(@"Error: %@ %@", error, [error userInfo]);
        }
    }];

self.listData = highScoreObjects;

I also tried keeping the line self.listData = highScoreObjects; inside the self.listData = highScoreObjects; loop. This didn't make any difference.

2 Answers 2

2

It isn't that it isn't set. It's that it isn't set yet. This is because you're using findObjectsInBackgroundWithBlock and the asynchronous process hasn't completed yet.

Move your assignment (self.listData = highScoreObjects;) into the block, just before you dispatch the request to reload the table view.

Sign up to request clarification or add additional context in comments.

1 Comment

Just to be safe, since highScoreData is mutable, I'd make sure self.listData is a copy of highScoreData. If you ever pass highScoreData somewhere else, and that code modifies it, self.listData will also get modified. That would be a frustrating bug to track down a year from now.
0

This is yet another case of not understanding the nature of asynchronous programming.

Consider this situation:

You want to make an egg sandwich. You put the eggs on to boil, and set an alarm for when they're cooked to get them out, peel them, cut them up and add them to your sandwich. While you wait you get the bread and butter it, then wait for the alarm to go off.

Your call to findObjectsInBackgroundWithBlock is putting the eggs on to boil. The block you pass it is the alarm and what you plan to do with the eggs once cooked.

Your code above is akin to putting the eggs on to boil, then straight away trying to use the uncooked/partially-cooked eggs on your sandwich. Makes a big mess.

The solution is to call a method at the end of the block your pass to the method.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.