在保留对象链接的同时向集合添加多个条目

时间:2011-06-21 15:54:56

标签: objective-c cocoa-touch cocoa core-data enumeration

我有一个关于在多个表中添加多个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];  
}

看起来代码运行正常,包括交叉引用,直到我添加使用所有其他托管对象的最终对象。该代码肯定存在一些问题。

1 个答案:

答案 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文档。)另一个可能的错误是您创建了两个上下文偶然。如果您正在使用线程,每个线程都有一个单独的上下文(必需的练习),那么您必须将背景上下文与前面上下文合并,然后才能在后台进行更改。