CoreData, NSManagedObject 获取或创建(如果不存在)

Posted

技术标签:

【中文标题】CoreData, NSManagedObject 获取或创建(如果不存在)【英文标题】:CoreData, NSManagedObject fetch or create if not exists 【发布时间】:2011-02-23 16:42:58 【问题描述】:

我正在尝试解析大量文本文件并将其内容组织为托管对象。文本文件中有很多重复项,因此“附带”任务之一就是删除它们。

我在这方面要做的是检查具有给定内容的实体是否存在,如果不存在,我创建一个。但是,我有具有不同属性和关系的不同实体。我想要的是一种将许多属性作为输入并返回一个新的 NSManagedObject 实例的函数,如果它被插入到数据存储中或从中获取,我不必担心。

有吗?

我还必须说我是核心数据的菜鸟。


更多细节,如果你愿意的话:

我正在尝试编写一种字典。我有单词(WordNSString *word, Rule rule),规则(RuleNSString name, >Word word, PartOfSpeech partOfSpeech, Ending endings),部分语音(PartOfSpeechNSString name, Rule rule)(我希望符号清晰)。

两个词是相等的,如果它们具有相同的词属性,并且“链接”到相同的规则。如果两个规则具有相同的结尾和词性,则它们是相同的。

到目前为止,我已经编写了一个将 NSPredicate、NSManagedObjectContext 和 NSEntityDescription 作为输入的方法,首先查询数据存储区,如果找到一个实体则返回一个实体,或者创建一个新实体,将其插入数据存储区并返回它.但是,在这种情况下,我无法用必要的数据(在该方法中)填充新实体,因此我必须传递一个带有属性名称及其值的 NSDictionary 并插入它们,或者通过引用返回一个标志是否我创建了一个新对象或返回了一个旧对象,以便我可以用外部数据填充它。

但它看起来有点丑。我敢肯定一定有比这更优雅的东西,我只是找不到它。如果可以,请你帮助我。

【问题讨论】:

【参考方案1】:

你基本上是在正确的道路上。 Core Data 是一个对象图。内置的动态并不多。也没有“upsert”。就像您猜测的那样,您必须获取,如果它不存在,则插入一个。

【讨论】:

【参考方案2】:

这是我刚刚开始用于处理 fetch-or-create 场景的内容。我正在使用一个***托管对象,其中包含与从属对象的几个对多关系。我有一个包含一些数据数组的类(此处未显示)。此类负责保存和检索核心数据。创建类后,我执行 fetch-or-create 来访问我的*** NSManagedObject。

@implementation MyDataManagerClass

...

@synthesize MyRootDataMO;

- (MyDataManagerClass *) init 

    // Init managed object

   NSManagedObjectContext *managedObjectContext = [(MyAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];

   // Fetch or Create root user data managed object

   NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"MyRootDataMO" inManagedObjectContext:managedObjectContext];
   NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];

   [request setEntity:entityDescription];

   NSError *error = nil;
   NSArray *result = [managedObjectContext executeFetchRequest:request error:&error];

   if (result == nil) 
       NSLog(@"fetch result = nil");
        // Handle the error here
    else 
       if([result count] > 0) 
           NSLog(@"fetch saved MO");
           MyRootDataMO = (MyRootDataMO *)[result objectAtIndex:0];
        else 
           NSLog(@"create new MO");
           MyRootDataMO = (MyRootDataMO *)[NSEntityDescription insertNewObjectForEntityForName:@"MyRootDataMO" inManagedObjectContext:managedObjectContext];
       

   

   return self;



...

【讨论】:

这适用于小型数据集,但在扩展到更大的数据集(例如字典或同义词库)时效率非常低。 这是 6 年前的代码。我不记得它是做什么用的,但它只在它的 init 中执行(注意它的返回自我 - 不是任何获取的结果)。从表面上看,这只会被调用很少次,可能只在应用程序启动时在单例初始化程序中调用一次,并且仅用于让自己访问托管对象树的单个入口点。然后可以扩展该类以创建核心数据的外观。 很公平,一个老问题的老答案,更多的是技术演示,而不是生产代码。 OP 正在询问该解决方案不适合的大规模数据设计模式。根本不是它错了,只是它不适合大型数据集。我自己在小型数据集上使用过这种技术,对于较大的数据集(例如 10,000 条记录),我使用获取的实体数据的 NSSet 在插入/更新之前确定成员资格。

以上是关于CoreData, NSManagedObject 获取或创建(如果不存在)的主要内容,如果未能解决你的问题,请参考以下文章

CoreData:将字符串转换为 NSManagedObject 实例

SWIFT CoreData NSManagedObject

保持 CoreData NSManagedObject 新鲜

如何在 CoreData 的代码中设置 NSManagedObject 与另一个 NSManagedObject 或它们的堆栈的关系?

调用 NSManagedObject 类上的指定初始化程序失败 - CoreData

CoreData:NSManagedObject 不响应用户定义的消息