[英]UITableView endUpdates not being called in dispatch_async
我有几个表视图,这些表视图将JSON请求发送到服务器,将结果存储在核心数据中,并使用NSFetchedResultsController
显示它们。 我正在尝试GCD,如下所示:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
// Perform JSON requests.
dispatch_async(dispatch_get_main_queue(), ^{
[theTableView reloadData];
});
});
但是,这会导致UI中发生一些奇怪的事情。 新的托管对象将呈现空白单元格,删除的托管对象将导致单元格重叠等。
但是,我发现如果执行此操作,所有内容将正确呈现。
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
dispatch_async(dispatch_get_main_queue(), ^{
[theTableView endUpdates];
});
}
我想知道的是,为什么这是必要的? 由于它是[theTableView reloadData]
的结果而触发,为什么它不自动包含在主队列中? 我以为可能是因为我没有明确称呼它。 在那种情况下,我是否必须同样包装所有功能?
我假设您从单独的线程中使用主NSManagedObjectContext
,这是不允许的。 对于后台导入,您必须创建一个单独的托管对象上下文,在该上下文中导入对象,然后将更改保存/合并到主上下文。
一种可能性是使用主管理对象上下文的子上下文:
NSManagedObjectContext *childContext = [[NSManagedObjectContext alloc]
initWithConcurrencyType:NSPrivateQueueConcurrencyType];
childContext.parentContext = mainManagedObjectContext;
[childContext performBlock:^{
// Perform JSON requests.
// Save objects to childContext.
NSError *error;
BOOL success = [childContext save:&error];
}];
“私有并发类型”的上下文创建其自己的队列/线程,以便performBlock
在后台执行(并且您需要/不必自己创建队列)。
保存childContext
更改合并到父mainManagedObjectContext
。 这足以使获取的结果控制器获得有关更改的通知,并更新表视图。
有关受管对象上下文并发和嵌套上下文的更多信息,请参见《 OS X v10.7和iOS 5.0的核心数据发行说明》 。
原为
[theTableView beginUpdates]
写在代码的任何地方? 尝试将其删除。 我怀疑UI怪异的事情正在发生,因为beginUpdates本身已经是异步的(不阻塞主线程),以便进行时髦的UITableView动画。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.