Основные данные многопоточное приложение


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

У меня есть NSURLConnection, который загружает файл асинхронно с помощью делегата (и показывает прогресс), затем я использую XMLParser для анализа новых данных и создания новых NSManagedObjects в отдельном контексте, с его собственным persistentStore и с помощью отдельного потока.

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

Паоло ака SlowTree

3 58

3 ответа:

параллелизм Apple с основной документацией данных это место, чтобы начать. Прочтите его очень внимательно... Меня много раз кусали мои недоразумения!

Основные правила:

  1. использовать один NSPersistentStoreCoordinator в программе. Вам не нужны они в потоке.
  2. создать NSManagedObjectContext в каждом потоке.
  3. никогда не пройти NSManagedObject на поток к другому потоку.
  4. вместо этого, получить идентификаторы объектов через -objectID и передать его другой поток.

правила:

  1. убедитесь, что вы сохранили объект в хранилище, прежде чем получить идентификатор объекта. Пока они не сохранены, они являются временными, и вы не можете получить к ним доступ из другого потока.
  2. и остерегайтесь политики слияния, если вы вносите изменения в управляемые объекты из нескольких потоков.
  3. NSManagedObjectContext ' s -mergeChangesFromContextDidSaveNotification: полезно.

но позвольте мне повторить, пожалуйста, внимательно прочитайте документ! Это действительно стоит того!

в настоящее время [Май 2015] на параллелизм Apple с документацией основных данных в лучшем случае очень вводит в заблуждение, поскольку он не охватывает никаких улучшений в iOS 5 и, следовательно, больше не показывает лучшие способы одновременного использования основных данных. Есть два очень важных изменения в iOS 5 - родительские контексты и новые типы параллелизма/потоков.

Я еще не нашел никакой письменной документации, которая всесторонне охватывает эти новые функции, но WWDC 2012 видео "Session 214-Core Data Best Practices" объясняет все это очень хорошо.

Магические Запись использует эти новые функции и, возможно, стоит посмотреть.

реальные основы все те же - вы все еще можете использовать управляемые объекты только в потоке, в котором был создан контекст управляемого объекта.

теперь вы можете использовать [moc performBlock:] для запуска кода в правом потоке.

нет необходимости использовать mergeChangesFromContextDidSaveNotification: больше; вместо этого создайте дочерний контекст, чтобы внести изменения, а затем сохраните дочерний контекст. Сохранение дочернего контекста автоматически переместит изменения в родительский контекст, а для сохранения изменений на диске просто выполните сохранение родительского контекста в его потоке.

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

mainManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];

затем на фоне потока:

context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSConfinementConcurrencyType];
[context setParentContext:mainManagedObjectContext];

<... perform actions on context ...>

NSError *error;
if (![context save:&error])
{
    <... handle error ...>
}
[mainManagedObjectContext performBlock:^{
    NSError *e = nil;
    if (![mainContext save:&e])
    {
        <... handle error ...>
    }
}];

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

взгляните на "Top Songs 2" в документации apple. С этим кодом я взял "красную таблетку" матрицы и открыл новый мир, без двойной свободной ошибки и без ошибок. : D

надеюсь, что это помогает.

Пауло

p.s. Большое спасибо Юджи, в документации, которую вы описали выше, я нашел этот пример.