Недостаточно памяти при выполнении миграции основных данных - PullRequest
8 голосов
/ 18 декабря 2010

Я мигрирую модель CoreData между двумя версиями приложения.В предыдущей версии я хранил двоичные данные в виде больших двоичных объектов, и я хочу вынести их из больших двоичных объектов для повышения производительности.Моя проблема в том, что во время миграции кажется, что Core Data загружает все в память, что приводит к предупреждению о нехватке памяти, а затем к тому, что мое приложение уничтожается.* Однако, похоже, полагается на то, что к крупным объектам применяются разные сопоставления.В моем случае все объекты в основном одинаковы, и к каждому из них должно быть применено одинаковое отображение.Я не вижу в этом случае, как я мог бы применить их технику.

Как мне справиться с миграцией с очень большими объектами?

1 Ответ

2 голосов
/ 09 января 2011

Я предполагаю, что у вас есть куча изменений, которые вы хотите внести в дополнение к извлечению данных из BLOB-объектов. Я предлагаю сделать миграцию в несколько этапов. Я тут немного обдумываю, так что можно улучшить это. Это требует, чтобы вы использовали SQLite.

Чтобы это работало, у вас будет три версии вашей модели:

  1. Оригинальная модель
  2. Модель с удаленным атрибутом (и, возможно, с добавлением специального уникального идентификатора - см. Ниже)
  3. Модель со всеми внесенными вами изменениями, включая добавление нового объекта и связей, заменяющих атрибут

Причина, по которой это делается, заключается в том, что переход с версии 1 на 2 должен быть осуществим при автоматической упрощенной миграции. В этом случае Core Data не нужно ничего загружать в память - он просто выдает операторы SQL, чтобы внести изменения непосредственно в базу данных.

Итак, вы начинаете с настройки постоянного координатора магазина с использованием старой версии модели. Как только вы загрузите данные, просмотрите все объекты, которые вы переносите, извлеките двоичный атрибут и каким-то образом запишите его на диск. Вы можете использовать запрос на выборку с пакетной обработкой и регулярным автоматическим удалением пула, чтобы убедиться, что вы не используете слишком много памяти для временных объектов. Сохраните данные в каталог, который вы получите с помощью NSCachesDirectory. Вы, очевидно, захотите хранить данные таким образом, чтобы вы могли связать их с управляющим объектом объекта.

Затем вы закрываете все и просите Core Data перенести хранилище из версии 1 в версию 2. Подробнее см. эту ссылку . Откройте магазин с версией 2.

Возможно, вам придется добавить шаг, в котором вы назначаете какой-то уникальный идентификатор каждому объекту, потому что я не уверен, поддерживает ли Core Data идентификаторы объекта, когда выполняется нелегкая миграция. Если вам нужно сделать это, ваша модель версии 2 добавит новый атрибут к объекту, из которого вы берите двоичные данные, который будет либо необязательным, либо будет иметь значение по умолчанию. Так как упрощенная миграция не должна изменять ManagedObjectID, вы могли бы сохранить сопоставление вашего нового уникального идентификатора с управляемым идентификатором ManagedObject, который вы сохранили вместе с двоичными данными два абзаца назад.

Сохраните данные и закройте магазин.

Откройте магазин и выполните переход с версии 2 на версию 3, которая в основном должна быть кодом, который вы уже написали до того, как опубликовали вопрос. Когда магазин будет открыт, добавьте все объекты, которые вы сохранили из магазина версии 1, и установите отношения, используя данные, которые вы сохранили по пути.

Простой, верно?

...