Импорт XML-файла объемом 100 МБ в базовую модель данных iOS - PullRequest
3 голосов
/ 11 мая 2011

В моем приложении мне нужно импортировать XML-файл размером 100 МБ в базовую модель данных.

Пока что я импортировал XML-файл размером 100 КБ, и все работает нормально. Тем не менее, не уверен, сколько времени потребуется для импорта 100 МБ 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));  

UPDATE Это однократная операция, которая выполняется только в симуляторе и не будет развернута с окончательным приложением.

Ответы [ 3 ]

4 голосов
/ 11 мая 2011

Я бы сделал следующие шаги:

3 голосов
/ 11 мая 2011

Помещение документа такого размера в резидентную память - это быстрый способ уничтожить ваше приложение системой.

Чтобы импортировать XML-документ большого размера в систему с ограниченными ресурсами, вам потребуется синтаксический анализ потока, что уменьшит объем резидентной памяти. Здесь есть много вариантов. NSXMLParser от Apple сделает свое дело, хотя и не так быстро, как некоторые альтернативы. (Хороший обзор этих альтернатив: здесь .)

Для реализации я предлагаю синтаксический анализ в подклассе NSOperation, периодически уведомляя основной поток с обновлениями прогресса. Это предотвратит блокирование пользовательского интерфейса при разборе произвольно больших документов.

Используя NSEntityDescription, вы создадите отдельные автоматически выпущенные объекты для каждого брата документа в XML-файле, что является еще одним быстрым способом нехватки памяти. Посмотрите документацию Apple Effectively Importing Data , чтобы узнать, как это сделать.

0 голосов
/ 11 мая 2011

Если это одноразовый процесс, используемый для создания базы данных CoreData или SQLite для распространения в вашем приложении, он, вероятно, будет работать, но только на симуляторе. Однако, если вам нужно выполнить это на устройстве, вам нужно переключиться на потоковый анализатор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...