在后台线程中使用MagicalRecord和NSXMLParser
我正在使用NSXMLParser来处理需要在我的Core Data模型中结束的大型复杂XML文件。为此,我按照Conway和Hillegass的iOS书籍中讨论的设计模式,在每次到达新节点和新节点动态创建时,更改NSXMLParser的委托。为了创建实体,我在解析期间为每个新节点使用MagicalRecord的MR_createEntity
来设置我的数据模型。解析完成后,我致电在后台线程中使用MagicalRecord和NSXMLParser
[[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait];
将新实体保存到我的Core Data存储中。
这一切工作正常,直到我最近决定将解析移动到后台线程。我注意到XML数据并不总是被导入。所以在谷歌搜索之后,我发现MR_createEntity
不应该用于后台线程(链接:https://github.com/magicalpanda/MagicalRecord/issues/298)。
那该怎么办?我看到了两个可能的解决方案:
-
,在分析,刚刚创建的所有节点的基础基于结构,NSDictionaries和NSArrays的混合物。这可以在后台线程上完成。一旦完成,我回到主线程并使用
而不是调用MR_importValuesForKeysWithObject
或类似的东西将我的数据保存到核心数据中(如此处所述:http://www.cimgf.com/2012/05/29/importing-data-made-easy/)。但是,这将与深嵌套字典和数组的组合工作吗?MR_CreateEntity
-
在解析,我用
[MagicalRecord saveInBackgroundWithBlock:^(NSManagedObjectContext *localContext) { MyEntity *entity = [MyEntity MR_createInContext:localContext]; }];
。
因此,在我开始切割和修改我的代码之前,要走的路是什么?也许还有另一种方法?
如果我理解正确的MagicalRecord源代码,你只需要一个单 saveInBackgroundWithBlock:completion:
电话:
[MagicalRecord saveInBackgroundWithBlock:^(NSManagedObjectContext *localContext) {
// ... parse XML ...
// ... create entities with:
MyEntity *entity = [MyEntity MR_createInContext:localContext];
// ...
} completion:^{
NSLog("Import finished");
}];
这
- 创建一个临时的背景下,
- 执行第一在与该上下文相关联的背景队列上阻塞,
- 个电话
MR_saveToPersistentStoreAndWait
到临时的上下文保存到 主要方面和保存主上下文持久核心, - 和最终执行完毕块。
你试试这个吗? 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不应该在后台线程上使用。所以我很困惑。
谢谢,我试过上面的代码,我可以看到所有正在执行的代码,但是在完成代码块中,我最终得到了“成功=否,错误= nil”(saveInBackgroundWithBlock已弃用,替换saveWithBlock有完成块中的BOOL和NSError)。所以数据没有保存到商店。我也使用[NSManagedObjectContext MR_contextForCurrentThread]在创建每个实体时获取localContext。也许这是错的? – Koen
@Koen:'saveWithBlock:completion' * should *也适用,但“成功=否,错误=零”很奇怪,我不知道为什么会发生这种情况。但是,我会避免使用'MR_contextForCurrentThread'(比较讨论http://stackoverflow.com/questions/17814656/passing-a-managedcontext-with-core-date-magical-record)。你应该使用传递给块的'localContext'。 –
我现在通过给所有实体一个上下文属性传递本地上下文以及解析器,现在它工作。仍不确定这是否是最有效的方式(与我原来的问题中的提案1相反)。我会在今天晚些时候或周末之后再看一遍。 – Koen