我有一个关于在多个表中添加多个CoreData条目的问题。
我有以下代码:
while((item = [enumerator nextObject]))
{
DOCategory *cat;
cat = [[self categoryController] getNewCategory];
[cat setName:[item objectForKey: @"name"]];
[cat setDesc:[item objectForKey: @"description"]];
[cat setLastUpdate:updateTime];
//[[self categoryController] commitChanges];
}
我曾经在每次枚举后调用commitChanges,这可行,但需要很长时间,特别是在较旧的设备上,因为初始负载相当大。因此我只想在整个操作结束时保存。
在保留指向ManagedContext的链接的同时,将所有这些对象添加到NSSet(或NSArray)的最佳方法是什么。通常我会将它们“复制”到集合中,但这在这里不起作用。一个简单的问题,只是看看最佳解决方案。
(我假设在创建的每个新对象之后我不必'提交/保存',因此结果不会写入数据库,但可用于搜索,因为过程中有不同的关系对象)
更新: 在下面的建议和更多测试之后,在我看来,当我没有保存/提交上下文时,它不包括NSFetchResultController。这是正确的,应该是这样的吗?有没有办法在'cache'中执行所有操作(包括搜索以创建关系),然后在完成所有操作后提交?
更新2: 为了获得Managed Object,我在Controller-class中有一个过程:
- (DOCategory *) getNewCategory{
return (DOCategory *)[NSEntityDescription insertNewObjectForEntityForName:@"Category" inManagedObjectContext:managedObjectContext];
}
看起来代码运行正常,包括交叉引用,直到我添加使用所有其他托管对象的最终对象。该代码肯定存在一些问题。
答案 0 :(得分:0)
您的代码是旧学校Objective-C 1.0,因此最好更新它。你很少直接使用这样的枚举器。
处理此问题的最佳方法是通过使用+[NSEntityDescription insertNewObjectForEntityForName:inManagedObjectContext:]
将它们插入上下文来创建新的托管对象,这将创建托管对象并使上下文知道它。上下文将保留托管对象本身。这就是“托管对象”的“管理”来自。
进行大量更改时的常规做法是更改所有对象,然后仅在完成所有更改后保存上下文。
看来代码运行正常, 包括交叉引用,直到我 来添加最终的对象 使用所有其他托管对象。 一定有一些问题 代码。
听起来您可能在数据模型本身中正确设置关系时遇到问题。我不能肯定地说不知道你的数据模型是什么样的。
我不鼓励使用insertNewObjectForEntityForName:
例如
(DOCategory *)[NSEntityDescription insertNewObjectForEntityForName:@"Category" inManagedObjectContext:managedObjectContext];
...因为如果您遇到数据模型问题,例如没有为DOCategory
实体提供DOCatergory
类的名称,则转换会模糊问题。如果没有定义类,则该方法将返回通用NSManagedObject
类的实例,或者如果您不小心为实体定义了错误的类,例如MadeUpClassName
而不是DOCategory
,然后强制转换将强制运行时将返回的对象视为DOCategory
对象。这可能会工作正常,直到在代码中向下。
......在我看来,当我没有 保存/提交它不是的上下文 包括NSFetchResultController。是 这是对的,应该是这样的? 有没有办法做到这一切 操作(包括搜索到 在'缓存'中创建关系)然后 一切都完成后提交?
不完全确定您看到的问题。最佳做法是对所有对象进行所有更改,然后保存上下文,而不是在每次更改任何单个对象后保存。磁盘操作很昂贵。
如果您对上下文的更改未反映在NSFetchResultsController(FRC)中,那么您很可能没有实现更新tableview的FRC委托方法(请参阅FRC文档。)另一个可能的错误是您创建了两个上下文偶然。如果您正在使用线程,每个线程都有一个单独的上下文(必需的练习),那么您必须将背景上下文与前面上下文合并,然后才能在后台进行更改。