CoreData: выпуск ManagedObject - PullRequest
       3

CoreData: выпуск ManagedObject

1 голос
/ 10 июля 2010

Я использую CoreData (с хранилищем SQLite) в приложении для iOS 4 для iPhone, чтобы хранить данные, которые я первоначально извлекаю из XML-файла.Моя модель данных содержит более 15 объектов, и я обеспокоен потреблением памяти, так как видел, как CoreData создает весь NSManagedObject в памяти для представления графа объектов моей модели данных.Я анализирую xml-файл с помощью синтаксического анализатора SAX libxml2 и пытаюсь сохранить каждый «набор агломератов» сущностей вместе по частям, но я бы хотел освободить каждый управляемый объект после того, как этот агломерат был вставлен, и управляемый контекст сохранен в порядкечтобы сохранить память для следующего агломерата.Я увидел, что мне нужно использовать refreshObject: mergeChanges: чтобы уравновесить многократное удержание, которое каждый объект получил, в то время как он связан с другими отношениями (как предусмотрено в модели данных).Я делаю это после сохранения контекста, но затем, когда я снова пытаюсь найти в магазине, пытаясь извлечь то, что я вставил, прежде чем он ничего не возвращает.Я что-то пропустил?

Ответы [ 3 ]

2 голосов
/ 10 июля 2010

Если все, что вы делаете, это импорт (например, вам не нужно сохранять вставленные объекты для отображения пользователю и т. Д.), Вы можете просто использовать [moc reset] после сохранения.Таким образом, алгоритм будет выглядеть примерно так:

NSManagedObjectContext* moc = ...;
while ([xmlData hasMoreObjects]) {
    // Create e.g. 500 objects and insert them into the managed object context
    NSError* error = nil;
    if (![moc save:&error]) {
        // handle the error
    }
    [moc reset]; // Here the inserted objects get released in the core data stack
}

Сброс контекста управляемого объекта выполняется так же, как если бы вы обновляли каждый объект (как вы делали это раньше).Также вам следует рассмотреть возможность использования [[NSManagedObject alloc] initWithEntity:insertIntoManagedObjectContext:] вместо вспомогательных методов на NSEntityDescription, потому что вы можете освободить их сразу после того, как они вам больше не нужны, и они не останутся в памяти, пока не будет очищен пул автоматического выпуска.1007 *

Взгляните на Руководство по программированию Core Data, так как оно содержит целый раздел, посвященный эффективному импорту данных, и один раздел, посвященный управлению памятью с помощью Core Data.

1 голос
/ 10 июля 2010

Вы не можете напрямую / вручную управлять памятью управляемых объектов, потому что контекст контролирует жизненный цикл объектов для поддержания целостности графа.

Если вы можете обрабатывать импорт в отдельных чанках, сохраняйте контекст после каждого чанка, а затем:

[context refreshObject:theObject mergeChanges:NO]

... который преобразует вновь сохраненные объекты в ошибки, поэтому они занимают очень мало памяти.

Вам нужны только ошибки, чтобы установить отношения, поэтому объекты, обработанные в предыдущем фрагменте, все еще будут доступны для установки в отношениях в текущем фрагменте.

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

Возможно, вы захотите проверить Руководство по программированию основных данных: Эффективный импорт данных , если вы еще этого не сделали.

0 голосов
/ 10 июля 2010

Я думаю, что вы должны делать это для каждого изменения

NSManagedObjectContext *moc;
NSError *error;
[moc save:&error];

В противном случае оно будет отброшено

...