我有一个JSON解析器,负责获取我想在UITableView
中显示的数据。一切似乎都是正确的,除了,当后台的块获取数据时,我无法重新加载表视图。
这就是我现在的做法:
-(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];
}
我尝试在任务准备就绪时调用函数,并在数组有内容时尝试重新加载表,但不幸的是有延迟,我无法从后台执行 UI 任务。
我的问题是,解决这个问题的最佳解决方案是什么?是否可以在 bg 线程之外以某种方式通知 reloadTable 方法?
您是否尝试在主线程上调用它?
- (void) reloadTable {
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
}
多线程控制器可能会变得复杂。这里有一些建议可以帮助您。
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.
}];
我在这里看到两个警告标志。
- 在主线程上创建的对象不应在后台更新。
- 不要在后台调用视图控制器方法。
简单的方法是立即调度到主线程。
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];
});
}];
还有许多其他处理主线程/后台线程交互的方法,但我会从这个开始。