将100MB XML文件导入iOS核心数据模型

时间:2011-05-11 13:47:27

标签: objective-c xcode ios core-data ipad

在我的应用中,我需要将100MB xml文件导入核心数据模型。

到目前为止,我已经导入了一个100KB的xml文件,一切正常。但是,不确定导入100MB xml需要多长时间。我会在一段时间内运行它。你觉得这种方法很好吗?

感谢

NSManagedObjectContext * context = [self managedObjectContext];

    // Delete all documents
    NSFetchRequest * fetch = [[[NSFetchRequest alloc] init] autorelease];
    [fetch setEntity:[NSEntityDescription entityForName:@"Document" inManagedObjectContext:context]];
    NSArray * result = [context executeFetchRequest:fetch error:nil];
    for (id basket in result)
        [context deleteObject:basket];



    //Insert documents
    TBXML * tbxml = [[TBXML tbxmlWithXMLFile:@"categ_small.xml"] retain];
    TBXMLElement * root = tbxml.rootXMLElement;
    TBXMLElement * doc = [TBXML childElementNamed:@"doc" parentElement:root];

    do {
        TBXMLElement * idDoc = [TBXML childElementNamed:@"id" parentElement:doc];
        TBXMLElement * titleDoc = [TBXML childElementNamed:@"title" parentElement:doc];
        TBXMLElement * descriptionDoc = [TBXML childElementNamed:@"description" parentElement:doc];
        TBXMLElement * time = [TBXML childElementNamed:@"time" parentElement:doc];
        TBXMLElement * tags = [TBXML childElementNamed:@"tags" parentElement:doc];
        TBXMLElement * geo = [TBXML childElementNamed:@"geo" parentElement:doc];
        TBXMLElement * event = [TBXML childElementNamed:@"event" parentElement:doc];
        TBXMLElement * user = [TBXML childElementNamed:@"user" parentElement:doc];
        TBXMLElement * categ = [TBXML childElementNamed:@"categ" parentElement:doc];

        NSManagedObject *newDocument = [NSEntityDescription
                                        insertNewObjectForEntityForName:@"Document"
                                        inManagedObjectContext:context];

        [newDocument setValue:[TBXML textForElement:idDoc] forKey:@"idDoc"];
        [newDocument setValue:[TBXML textForElement:titleDoc] forKey:@"titleDoc"];
        [newDocument setValue:[TBXML textForElement:descriptionDoc] forKey:@"descriptionDoc"];
        [newDocument setValue:[TBXML textForElement:time] forKey:@"time"];
        [newDocument setValue:[TBXML textForElement:tags] forKey:@"tags"];
        [newDocument setValue:[TBXML textForElement:geo] forKey:@"geo"];
        [newDocument setValue:[TBXML textForElement:event] forKey:@"event"];
        [newDocument setValue:[TBXML textForElement:user] forKey:@"user"];
        [newDocument setValue:[TBXML textForElement:categ] forKey:@"categ"];

    } while ((doc = doc->nextSibling));  

更新 这是一次性操作,仅在模拟器中运行,不会与最终应用程序一起部署。

3 个答案:

答案 0 :(得分:4)

我会执行以下步骤:

  • 使用ruby或php编写转换器XML-> SQLite,或者如果您不是脚本语言的朋友,那么看看SQLite Manager它是一个管理SQLite数据库的Firefox插件,它能够导入XML

  • 按照本教程预先填充核心数据以供发货:How To Preload/Import Existing Data

答案 1 :(得分:3)

将大小放在常驻内存中的文档是让您的应用程序被系统杀死的快捷方法。

要在具有有限资源的系统上导入大型XML文档,您需要进行流式解析,这样可以减少驻留内存占用空间。这里有很多选择。苹果公司的NSXMLParser可以解决这个问题,尽管它并不像某些替代方案那么快。 (对这些替代方案的一个很好的概述是here。)

对于实现,我建议在NSOperation子类中进行解析,定期通过进度更新通知主线程。这将阻止UI在您解析任意大型文档时阻塞。

使用NSEntityDescription的方式将为XML文件中的每个doc兄弟创建单独的自动释放对象,这是另一种运行内存不足的快速方法。请查看Apple的Efficiently Importing Data文档,了解正确的方法。

答案 2 :(得分:0)

如果这是用于构建CoreData或SQLite数据库以与您的应用程序一起分发的一次性过程,它可能会起作用,但仅限于模拟器上。但是,如果您需要在设备上执行此操作,则需要切换到流式解析器。