Reputation: 3350
I have a JSON parser that is responsible for getting the data that I would like to display in a UITableView
. Everything seems to be correct, except, that I can't reload the table view when the block in the background obtained the data.
This is how I do it now:
-(void)viewWillAppear:(BOOL)animated {
self.arr =[[NSMutableArray alloc] init];
self.api = [API new];
[self.api requestWithCompletionHandler:^(NSArray<NSDictionary *> * result, NSError * error) {
for (NSDictionary* x in result) {
NSLog(@"The whole dict object: %@", [x objectForKey:@"datum"]);
//NSString *grr = [NSString stringWithString:[x objectForKey:@"datum"]];
[self.arr addObject:x];
}
[self reloadTable];
}];
// if (self.arr.count > 1) {
// [self reloadTable];
// }
//
}
- (void) reloadTable {
[self.tableView reloadData];
}
I tried to call a function when the task is ready, and also tried to reload the table when the array has content, but unfortunately there is a delay, and I can't do a UI task from the background.
My question is, that what would be the best solution to fix this? Is is possible to notify the reloadTable method somehow outside from the bg thread?
Upvotes: 0
Views: 59
Reputation: 42588
multi-threaded controllers can get complicated. Here is some advice to help you out.
self.api = [API new]; // 1a: Created in the main thread.
[self.api requestWithCompletionHandler:^(NSArray<NSDictionary *> *result, NSError *error) {
for (NSDictionary* x in result) {
NSLog(@"The whole dict object: %@", [x objectForKey:@"datum"]);
[self.arr addObject:x]; // 1b: Updated in the background.
}
[self reloadTable]; // 2: Calling a view controller method in the background.
}];
I see two warning flags here.
The easy way out is to dispatch to the main thread right away.
self.api = [API new];
[self.api requestWithCompletionHandler:^(NSArray<NSDictionary *> *result, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
for (NSDictionary* x in result) {
NSLog(@"The whole dict object: %@", [x objectForKey:@"datum"]);
[self.arr addObject:x];
}
[self reloadTable];
});
}];
There are many other ways of handling main thread/background thread interactions, but I would start with this.
Upvotes: 1
Reputation: 7270
Have you tried to call it on the main thread?
- (void) reloadTable {
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
}
Upvotes: 3