Если вы не используете какую-либо внешнюю библиотеку, такую как Magical Record или RestKit, а просто загружаете все ручные материалы, вы можете воспользоваться новыми API-интерфейсами NSManagedObjectContext
.
Теперь вы можете иметь контексты, вложенные в отношения родитель-потомок, и вы также можете сообщить каждому контексту о выполнении блока в его собственном потоке. Поэтому мой совет должен иметь следующую структуру для вашей заявки:
1) Контекст сохранения фона. Это будет единственный контекст, который сохраняет и считывает данные непосредственно в/из базы данных.
2) Контекст, инициированный в основном потоке, который будет вашей точкой доступа для всего, что вам нужно сделать в приложении, особенно для обновления пользовательского интерфейса. Этот контекст будет дочерним элементом контекста сохранения.
3) При необходимости вы создадите фоновые контексты, которые выполняют работу с фоновыми потоками, например. загрузка данных из сети и сериализация этих данных в экземплярах NSManagedObject. Этими контекстами будут дети основного контекста.
4) Каждый раз, когда вы вызываете -[NSManagedObjectContext save:]
в контексте, вы также должны вызывать тот же метод в его parentContext. Чтобы сделать это, вы могли бы иметь удобный метод в категории на NSManagedObjectContext, который читает что-то вроде этого:
- (void)saveSelfAndParent {
[self save:NULL];
[self.parentContext performBlock:^{
[self.parentContext saveSelfAndParent];
}];
}
Это уже безопасная конфигурация потоков и изменения будут распространяться изменения к базе данных. Обратите внимание, что поскольку контекст сохранения не будет иметь родителя (и, таким образом, self.parentContext будет равен нулю), executeBlock: не приведет к сбою приложения.
Вот пример того, что вам нужно сделать, чтобы создать новый объект если вы пнуть фоновую работу с помощью Grand Central Dispatch (GCD):
dispatch_async(dispatch_async_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType: NSPrivateQueueConcurrencyType];
context.parentContext = mainContext;
// do some expensive job
...
// initialize a new NSManagedObject instance using the information we calculated
NSManagedObject *myObject = ...;
// once we're done, let's save the context
[context saveSelfAndParent];
});
Обратите внимание, что мы инициализированный контекст с частной параллельностью очереди type (NSPrivateQueueConcurrencyType), который указывает контексту, что он фоновый контекст. Это очень важно!
Вот и все! :)
Для получения дополнительной информации обратитесь к NSManagedObjectContext Class Reference.
RestKit по-прежнему загружает и сохраняет все на фоне потоков ... – Wain