在后台线程中使用MagicalRecord和NSXMLParser

时间:2013-08-31 01:54:43

标签: ios objective-c nsxmlparser magicalrecord

我正在使用NSXMLParser来处理需要最终在我的Core Data模型中的大型复杂XML文件。为此,我遵循Conway和Hillegass在iOS书中讨论的设计模式,每次到达新节点时都会更改NSXMLParser的委托,并且动态创建新节点。为了创建实体,我在解析期间为每个新节点使用MagicalRecord的MR_createEntity来设置我的数据模型。解析完成后,我打电话

[[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait]; 

将新实体保存到我的Core Data商店。

这一切都很好,直到我最近决定将解析移动到后台线程。我注意到XML数据并不总是被导入。因此,经过一些谷歌搜索后,我发现MR_createEntity不应该在后台线程上使用(链接:https://github.com/magicalpanda/MagicalRecord/issues/298)。

那该怎么办?我看到两种可能的解决方案:

  1. 在解析过程中,只需创建所有节点的基于Foundation的结构,即NSDictionaries和NSArrays的混合体。这可以在后台线程上完成。完成后,我将返回主线程并使用MR_importValuesForKeysWithObject或类似内容(如此处所述:http://www.cimgf.com/2012/05/29/importing-data-made-easy/)将我的数据保存到Core Data中。但是,这是否可以与深层嵌套的词典和数组的组合一起使用?

  2. 在解析过程中,我使用

    而不是调用MR_CreateEntity
    [MagicalRecord saveInBackgroundWithBlock:^(NSManagedObjectContext *localContext)
    {
        MyEntity *entity = [MyEntity MR_createInContext:localContext];
    }];
    
  3. 每次我按照上面github链接中的建议来到新节点。

    所以在我开始切割和修改代码之前,还有什么方法可以解决?也许有另一种方法?

2 个答案:

答案 0 :(得分:1)

如果我正确理解了MagicalRecord源代码,则只需要单个 saveInBackgroundWithBlock:completion:致电:

[MagicalRecord saveInBackgroundWithBlock:^(NSManagedObjectContext *localContext) {
      // ... parse XML ...
      // ... create entities with:
      MyEntity *entity = [MyEntity MR_createInContext:localContext];
      // ...
} completion:^{
    NSLog("Import finished");
}];

  • 创建临时背景上下文
  • 执行与该上下文相关联的后台队列上的第一个块
  • 调用MR_saveToPersistentStoreAndWait将临时上下文保存到 主要上下文将主要上下文保存到持久性核心
  • 最后执行完成块。

答案 1 :(得分:0)

你试试这个吗? https://stackoverflow.com/a/13924299/1979953

像这样。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  // dispatch_async mean your NSXMLParser in a backgound thread
  MyEntity *entity = [MyEntity MR_createEntity];

  ...

  [[NSManagedObjectContext MR_contextForCurrentThread] saveNestedContexts];
});

但是,您发现不应在后台线程上使用MR_createEntity。所以我很困惑。