Основные данные многопоточное приложение
Я пытаюсь использовать основные данные в многопоточном способе. Я просто хочу показать приложение с ранее загруженными данными при загрузке новых данных в фоновом режиме. Это должно позволить пользователю получить доступ к приложению во время процесса обновления.
У меня есть NSURLConnection, который загружает файл асинхронно с помощью делегата (и показывает прогресс), затем я использую XMLParser для анализа новых данных и создания новых NSManagedObjects в отдельном контексте, с его собственным persistentStore и с помощью отдельного потока.
проблема заключается в том, что создание новых объектов в том же контексте старого, показывая его может бросает BAD_INSTRUCTION исключение. Итак, я решил использовать отдельный контекст для новых данных, но я не могу понять, как переместить все объекты в другой контекст После завершения.
Паоло ака SlowTree
3 ответа:
параллелизм Apple с основной документацией данных это место, чтобы начать. Прочтите его очень внимательно... Меня много раз кусали мои недоразумения!
Основные правила:
- использовать один
NSPersistentStoreCoordinator
в программе. Вам не нужны они в потоке.- создать
NSManagedObjectContext
в каждом потоке.- никогда не пройти
NSManagedObject
на поток к другому потоку.- вместо этого, получить идентификаторы объектов через
-objectID
и передать его другой поток.правила:
- убедитесь, что вы сохранили объект в хранилище, прежде чем получить идентификатор объекта. Пока они не сохранены, они являются временными, и вы не можете получить к ним доступ из другого потока.
- и остерегайтесь политики слияния, если вы вносите изменения в управляемые объекты из нескольких потоков.
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. Большое спасибо Юджи, в документации, которую вы описали выше, я нашел этот пример.