Reputation: 11098
Example:
[query findObjectsInBackgroundWithBlock:^(NSArray *favObjects, NSError *error) {
for (PFObject *favObject in favObjects) {
dispatch_async(dispatch_get_main_queue(), ^{
[cell setSizeLabel:[_arrayOfSizes objectAtIndex:[[favObject valueForKey:@"size"] integerValue]]];
[[cell sizeDropDownButton] setTitle:[cell sizeLabel] forState:UIControlStateNormal];
});
if ([[[cell currentObject] valueForKey:@"alternativeColour"] boolValue]) {
// Colours are stored in db on parse as numbers, I use array below to determine which colour is being red back by valueForkey below
dispatch_async(dispatch_get_main_queue(), ^{
[cell setColourLabel:[_arrayOfColours objectAtIndex:[[favObject valueForKey:@"colour"] integerValue]]];
[[cell colourDropDownButton] setTitle:[cell colourLabel] forState:UIControlStateNormal];
});
}
[[cell priceLabelSpinner] stopAnimating];
[[cell titleLabelSpinner] stopAnimating];
[[cell sizeDropDownButton] setHidden:NO];
[[cell colourDropDownButton] setHidden:NO];
}
}];
You can see I'm setting the the buttons label titles on the main queue. However below I'm stopping a the spinned on the background queue as well as unhiding buttons. Is this correct?
Upvotes: 0
Views: 73
Reputation: 15015
As per Apple Documentation
all UI
updates should happen in main thread. So have modified your code and also include all UI
updates in single dispatch_async
block, try below:-
[query findObjectsInBackgroundWithBlock:^(NSArray *favObjects, NSError *error) {
for (PFObject *favObject in favObjects) {
dispatch_async(dispatch_get_main_queue(), ^{
[cell setSizeLabel:[_arrayOfSizes objectAtIndex:[[favObject valueForKey:@"size"] integerValue]]];
[[cell sizeDropDownButton] setTitle:[cell sizeLabel] forState:UIControlStateNormal];
if ([[[cell currentObject] valueForKey:@"alternativeColour"] boolValue]) {
// Colours are stored in db on parse as numbers, I use array below to determine which colour is being red back by valueForkey below
[cell setColourLabel:[_arrayOfColours objectAtIndex:[[favObject valueForKey:@"colour"] integerValue]]];
[[cell colourDropDownButton] setTitle:[cell colourLabel] forState:UIControlStateNormal];
}
[[cell priceLabelSpinner] stopAnimating];
[[cell titleLabelSpinner] stopAnimating];
[[cell sizeDropDownButton] setHidden:NO];
[[cell colourDropDownButton] setHidden:NO];
}
}];
Upvotes: 0
Reputation: 12200
Anything that can cause you view change should be called from main thread:
Manipulations to your application’s user interface must occur on the main thread. Thus, you should always call the methods of the UIView class from code running in the main thread of your application. The only time this may not be strictly necessary is when creating the view object itself but all other manipulations should occur on the main thread.
So taking into account what's suggested by Apple you should rewrite your code to:
[query findObjectsInBackgroundWithBlock:^(NSArray *favObjects, NSError *error) {
for (PFObject *favObject in favObjects) {
dispatch_async(dispatch_get_main_queue(), ^{
[cell setSizeLabel:[_arrayOfSizes objectAtIndex:[[favObject valueForKey:@"size"] integerValue]]];
[[cell sizeDropDownButton] setTitle:[cell sizeLabel] forState:UIControlStateNormal];
});
if ([[[cell currentObject] valueForKey:@"alternativeColour"] boolValue]) {
// Colours are stored in db on parse as numbers, I use array below to determine which colour is being red back by valueForkey below
dispatch_async(dispatch_get_main_queue(), ^{
[cell setColourLabel:[_arrayOfColours objectAtIndex:[[favObject valueForKey:@"colour"] integerValue]]];
[[cell colourDropDownButton] setTitle:[cell colourLabel] forState:UIControlStateNormal];
});
}
dispatch_async(dispatch_get_main_queue(), ^{
[[cell priceLabelSpinner] stopAnimating];
[[cell titleLabelSpinner] stopAnimating];
[[cell sizeDropDownButton] setHidden:NO];
[[cell colourDropDownButton] setHidden:NO];
});
}
}];
Upvotes: 3
Reputation: 4673
Stopping animating or hiding views are also UI operations, so they must be done on main thread as well.
Upvotes: 2