2010-11-04 64 views
24

我已经掌握了使用核心数据插入记录和删除记​​录的基本知识;然而,我会很感激帮助最常用的功能之一 - 插入/更新如何使用核心数据执行插入/更新

基本上,我用NSMutableArrayarrayWithContentsOfURL来获取一个包含mysql表的行的数组。我需要做的是现在同步我的店面。

换句话说,我需要将数组中的每一行添加到我的CoreData表中,但是如果它已经存在,我需要用最新值更新记录。此外,如果它存在于核心数据而不是下载的数组中,我需要将其删除。

我大概可以一起破解这个;然而,我想看看它是如何正确和高效地完成没有内存泄漏。

+0

我知道这已经晚了,但是如果你从数组中不存在的核心数据中删除项目,为什么不删除核心数据中的所有项目并插入所有新项目。插入vs更新存在的可能更容易。 – Ben 2012-03-05 09:39:37

+0

@Ben:很好的建议,但是这不会太慢吗?特别是在有许多条目的桌子的情况下,只有一对需要更改。在你不需要的时候做这么多的写作可能很重要,对吗? – GeneralMike 2012-10-03 17:28:59

+0

@GeneralMike如果你有很多行,肯定会更有效率。我当时还没有学会正确的方法来做到这一点:) – Ben 2012-10-06 13:45:38

回答

34

有两种方法可以将数据插入核心数据 - 无论您使用哪种方法都取决于您。但是,其中一个取决于您是否为Core Data数据库的数据模型生成了Model类。

常规的方法是使用以下命令:

NSManagedObject *object = [NSEntityDescription insertNewObjectForEntityForName:@"table" 
inManagedObjectContext:context]; 
[object setValue:@"value1" forKey:@"stringColumn"]; 
[object setValue:12 forKey:@"numberValue"]; 
NSError *error; 
if (![context save:&error]) { 
    NSLog(@"Failed to save - error: %@", [error localizedDescription]); 
} 

这是假设你已经得到了你的管理对象范围内设立。 如果您创建对象并将其插入循环中的上下文,然后在循环结束后保存,效率会更高。

另一种方法没有多大区别,但在类型安全性方面更安全。如果您生成了模型类(您可以从 xcdatamodels中完成),那么您可以简单地创建该类的对象并设置其属性。

TableObject *object = [NSEntityDescription insertNewObjectForEntityForName:@"table" 
inManagedObjectContext:context]; 
[object setStringColumn:@"value1"]; 
[object setNumberValue:12]; 
NSError *error; 
if (![context save:&error]) { 
    NSLog(@"Failed to save - error: %@", [error localizedDescription]); 
} 

若要从表中删除,只需从表中检索对象(我假设你在这里使用第二种方法用于插入,因此已生成的模型类),并使用下列内容:

[context deleteObject:object]; 

请注意,您需要调用save才能生效。

希望这会有所帮助!祝你好运!编辑: 对不起,我一定误会了这个问题!

要检查现有记录,您需要创建一个Fetch Request,然后在您的托管对象上下文中执行它。 最低限度,Fetch Request需要一个实体(因此它知道要在哪个表上进行搜索)。 要指定搜索条件,您需要创建一个谓词(否则请求将简单地返回表中的所有内容)。您还可以指定一组排序描述符,以便对结果进行排序。

NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease]; 
NSEntityDescription *entity = [NSEntityDescription entityForName:@"table" inManagedObjectContext:context]; 
[request setEntity:entity]; 

NSError *errorFetch = nil; 
NSArray *array = [context executeFetchRequest:request error:&errorFetch]; 

此代码创建一个提取请求,并返回数组中的表“table”中的每个对象。 从这里开始,由于所有必需的对象都位于数组中,因此您可以检查和编辑记录。如果您进行任何更改,请记住保存上下文! 以下循环使用与上述示例相同的表记录每个对象中的第一个值。

for(TableObject *object in array) 
{ 
    NSLog(@"object value1 = %@", object.value1); 
} 

您还可以使用上述功能删除这一点的记录。

有关提取请求的更多信息,请给class reference一看。我还强烈建议阅读关于排序描述符和谓词的内容,因为它们对于搜索Core Data数据库非常重要,并且它们的某些用途效率低于其他用户(特别是在创建NSPredicates时)。

祝你好运!

+0

嗨安德鲁,感谢您的答复。我已经知道如何使用NSManagedObject将记录插入到Core Data中,就像我在问题中提到的那样。我正在寻求代码的帮助来检查核心数据中已经存在的记录,然后更新它们,删除它们,或者根据下载的NSMutableArray中的记录插入新记录。 – slevytam 2010-11-05 00:54:26