另一种多线程核心数据使用

Posted

技术标签:

【中文标题】另一种多线程核心数据使用【英文标题】:Another multi-threading core-data use 【发布时间】:2012-02-27 23:00:43 【问题描述】:

我对 Core Data 完全陌生,我想知道我想做的以下任务的最佳方法(即使我应该使用 Core Data):

我有几个实体,它们之间具有不同的一对一和一对多关系。

我想在表格视图中向用户显示一组“综合”信息

要获得“综合”信息,我要做的不仅仅是获取一些行。我需要获取一些实体,根据一些算法对其进行过滤,计算一些信息(存储在瞬态属性中)等等。

一旦我得到结果(一组减少的实例),我想向用户展示它

因为这是一项繁重的任务,我想在单独的后台线程中执行它

就是说,当我准备好一组选定的 ManagedObject 时:

我是否应该只将它们的“ID”传递给主线程,以便在主 ManagedContext 中重新获取它们?我可以对计算出的瞬态信息做什么(与表格单元格中的其他数据一起显示)。

难道我不能把它们传回去只是为了展示吗?

对于最后一个问题,我是否可以“锁定” ManagedContext 以确保数据顺利通过(我读到这可能是一个选项)?

Core Data 是否适合这种用途?我应该考虑另一种方法/技术吗?

提前致谢

【问题讨论】:

【参考方案1】: 我是否应该只将它们的“ID”传递给主线程以便重新获取 它们在主 ManagedContext 中?我可以用瞬态做什么 计算出的信息(与表格中的其他数据一起显示) 细胞)。 难道我不能把它们传回去只是为了展示吗?

无需传递 id,您可以轻松调用 NSOperation 进行计算并检索和存储您的对象集,然后在计算结束时调用:

[tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES];

这将触发表再次调用其委托选择器。重要的是您必须将检索到的对象存储在委托选择器可以访问的数据源中,例如可以是 NSArray:

@property(nonatomic,strong) NSArray *datasource;

-(void)loadDataAsynchronously 

    NSOperationQueue *queue = [NSOperationQueue new];
    NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
                                                                            selector:@selector(loadData)
                                                                              object:nil];

    [queue addOperation:operation];


-(void)loadData
  // do your calculation and store into array
  self.datasource=......

  // reload on main thread
  [tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES];


- (UITableViewCell *)tableView:(UITableView *)table cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    YourObject *obj = [[self datasource] objectAtIndex:indexPath.row];
    YourTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"tableCell"];
    cell.cellTitle.text=obj.titleForCell;
    cell.cellDescr.text=obj.descriptionForCell;
    return cell;

对于最后一个问题,我是否可以“锁定” ManagedContext 以确保数据顺利通过(我读到这可能是一个选项)?

一旦您检索到对象,如果您有一个只读表,则无需锁定 CoreData。否则,如果您知道后台线程可能已经更改了您已显示的数据,并且您的表格可以被编辑和保存,那么您必须制定一个繁重的逻辑来处理它。否则您将收到“不一致错误”。但是,如果您有一个只读表,例如,如果有人更改了数据,您可以提醒控制器,并要求他们重新加载表。

Core Data 是否适用于此用途?我应该考虑另一种方法/技术吗?

是的,您应该注意的唯一一点是您正在执行哪种计算。最常见的错误是将 CoreData 视为 SQL 数据库而不是对象图(这是我最常犯的错误),因此无法进行许多粒子和准确的类似 sql 的操作。在许多情况下,您将最终检索基于标准的集合,您必须在此基础上进一步进行内存计算。但老实说,尽管很多人说,除非你有数千条记录,否则我发现所有 ios 设备在这方面都非常快,可以获得合理的数据量。

【讨论】:

感谢您的回答。 我问了第一个问题,因为它总是说“永远不要跨越线程边界”。 我来自Java编程,并且“不是线程安全的”与“不要在线程之间传递它”不同。你只需要知道你在做什么并明智地使用“同步”。但是,某些信息可能会绑定到线程,这可能是原因。 我的代码其实和你的很相似。

以上是关于另一种多线程核心数据使用的主要内容,如果未能解决你的问题,请参考以下文章

一种多线程变量区域锁的实现方法

两种多线程创建方式区别

JAVA三种多线程实现方法和应用总结

多线程编程GCD

java 两种多线程实现

java核心-多线程-线程类基础知识