Я пытаюсь использовать базовые данные во много потоке путь. Я просто хочу показать приложение с ранее загруженными данными при загрузке новых данных в фоне. Это должно позволить пользователю получить доступ к приложению во время процесса обновления.
У меня есть NSURLConnection, которые загружают файл асинхронно с помощью делегата (и показывая прогресс), затем я использую XMLParser, чтобы проанализировать новые данные и создать новый NSManagedObjects в отдельном контексте с его собственным persistentStore и использованием отдельного потока.
Проблема состоит в том, что, создавая новые объекты в том же контексте старого при показе это может броски исключение BAD_INSTRUCTION. Так, я решил использовать отдельный контекст для новых данных, но я не могу выяснить способ переместить все объекты в другой контекст, однажды законченный.
Паоло иначе SlowTree
Параллелизм Apple с Базовой документацией Данных является местом для запуска. Считайте его действительно тщательно... Я много раз кусался моими недоразумениями!
Основные правила:
NSPersistentStoreCoordinator
на программу. Вам не нужны они на поток. NSManagedObjectContext
на поток. NSManagedObject
потоку к другому потоку. -objectID
и передайте его другому потоку.
NSManagedObjectContext
-mergeChangesFromContextDidSaveNotification:
полезно. , Но позволяют мне повториться, прочитайте документ тщательно! Это действительно стоит того!
В настоящее время [май 2015] Параллелизм Apple с Базовой документацией Данных , в лучшем случае очень вводящий в заблуждение, поскольку это не покрывает ни одного из улучшений в iOS 5 и следовательно больше не показывает лучшие способы использовать базовые данные одновременно. Существует два очень важных изменения в iOS 5 - родительские контексты и новые типы параллелизма/поточной обработки.
я еще не нашел записанной документации, которая всесторонне касается этих новых возможностей, но видео "Сессия 2012 года WWDC 214 - Базовые Лучшие практики Данных" действительно объясняют все это очень хорошо.
Волшебная Запись использует эти новые функции и может быть достойная внимания.
реальные основы являются все еще тем же - можно все еще только использовать управляемые объекты поток, на котором был создан их контекст управляемого объекта.
можно теперь использовать [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 ...>
}
}];
Я надеюсь, что это может помочь всем народам, которые встречают проблемы с помощью базовых данных в среде мультипотока.
Смотрят на "Главные Песни 2" в документации яблока. С этим кодом я принял "красную таблетку" Матрицы и обнаружил новый мир без двойной бесплатной ошибки, и без отказов. :D
Hope это помогает.
Paolo
p.s. Большое спасибо Yuji, в документации, которую Вы описали выше, я нашел тот пример.