在后台线程中使用 MagicalRecord 和 NSXMLParser [英] Using MagicalRecord and NSXMLParser in a background thread
问题描述
我正在使用 NSXMLParser 来处理需要在我的核心数据模型中结束的大型复杂 XML 文件.为此,我遵循 Conway 和 Hillegass 在 iOS 书中讨论的设计模式,每次到达新节点并动态创建新节点时,NSXMLParser 的委托都会更改.为了创建实体,我在解析过程中为每个新节点使用 MagicalRecord 的 MR_createEntity
以设置我的数据模型.解析完成后我调用
I'm using an NSXMLParser to process a large and complex XML file that needs to end up in my Core Data model. To do this I am following the design pattern as discussed in the iOS book by Conway and Hillegass, where the delegate of the NSXMLParser is changed every time a new node is reached and new nodes are created on the fly. To create the entities, I am using MagicalRecord's MR_createEntity
for each new node during the parsing to set up my data model. After the parsing is finished I call
[[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait];
将新实体保存到我的核心数据存储中.
to save the new entities to my Core Data store.
这一切都很好,直到我最近决定将解析移到后台线程中.我注意到 XML 数据并不总是被导入.因此,经过一番谷歌搜索后,我发现 MR_createEntity
不应该用于后台线程(链接:https://github.com/magicalpanda/MagicalRecord/issues/298).
This all works fine, until I recently decided to move the parsing into a background thread. And I noticed the XML data was not always imported. So after some Googling I found that MR_createEntity
should not be used on a background thread (link: https://github.com/magicalpanda/MagicalRecord/issues/298).
那怎么办?我看到了两种可能的解决方案:
So what to do? I see two possible solutions:
在解析过程中,只需为所有节点创建一个基于 Foundation 的结构,即 NSDictionaries 和 NSArrays 的混合体.这可以在后台线程上完成.完成后,我返回主线程并使用
MR_importValuesForKeysWithObject
或类似的东西将我的数据保存到 Core Data 中(如下所述:http://www.cimgf.com/2012/05/29/importing-data-made-easy/).但这是否适用于深度嵌套的字典和数组的组合?
During the parsing, just create a Foundation based structure of all the nodes, a mixture of NSDictionaries and NSArrays. This can be done on a background thread. Once done, I go back to the main thread and save my data into Core Data using
MR_importValuesForKeysWithObject
or something similar (as described here: http://www.cimgf.com/2012/05/29/importing-data-made-easy/). But will that work with combinations of deeply nested dictionaries and arrays?
在解析过程中,我没有调用MR_CreateEntity
,而是使用
During the parsing, instead of calling MR_CreateEntity
, I use
[MagicalRecord saveInBackgroundWithBlock:^(NSManagedObjectContext *localContext)
{
MyEntity *entity = [MyEntity MR_createInContext:localContext];
}];
每当我遇到上面 github 链接中建议的新节点时.
every time I come upon a new node as suggested in the github link above.
那么在我开始削减和修改我的代码之前,应该怎么做?也许还有另一种方法?
So before I start cutting up and modifying my code, what would be the way to go? Maybe there is another approach?
推荐答案
如果我正确理解 MagicalRecord 源代码,你只需要一个单saveInBackgroundWithBlock:completion:
调用:
If I understand the MagicalRecord source code correctly, you need only a single
saveInBackgroundWithBlock:completion:
call:
[MagicalRecord saveInBackgroundWithBlock:^(NSManagedObjectContext *localContext) {
// ... parse XML ...
// ... create entities with:
MyEntity *entity = [MyEntity MR_createInContext:localContext];
// ...
} completion:^{
NSLog("Import finished");
}];
这个
- 创建一个临时的背景上下文,
- 执行与该上下文关联的后台队列中的第一个块,
- 调用
MR_saveToPersistentStoreAndWait
将临时上下文保存到主上下文和将主上下文保存到持久化核心, - 最后执行完成块.
- creates a temporary background context,
- executes the first block on the background queue associated with that context,
- calls
MR_saveToPersistentStoreAndWait
to save the temporary context to the main context and save the main context to the persistent core, - and finally executes the completion block.
这篇关于在后台线程中使用 MagicalRecord 和 NSXMLParser的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!