Кажется, что в ноябре Apple обновила и NSManagedObjectContext Reference Reference и Руководство по программированию основных данных", чтобы явно благословлять серийные очереди GCD и NSOperationQueues в качестве приемлемых механизмов для синхронизации доступа к NSManagedObjectContext
. Но их советы кажутся двусмысленными и, возможно, противоречивыми, и я хочу убедиться, что правильно понял.
Раньше общепринятая мудрость заключалась в том, что NSManagedObjectContext
можно было получить только из потока, который ее создал, и что использование последовательной очереди для синхронизации было недостаточным; хотя последовательные очереди выполняют только одну операцию за раз, эти операции могут быть запланированы на разных потоках, а MOC это не нравится.
Но теперь из руководства по программированию мы имеем:
Вы можете использовать потоки, очереди очередей или очереди отправки для concurrency. Для краткости в этой статье используется "поток" для ссылки на любой из них.
Пока, так хорошо (хотя их объединение потоков и очередей бесполезно). Таким образом, я могу безопасно использовать единый контекст для (последовательной) очереди, а не один за операцию/блок, правильно? Apple даже имеет наглядное представление об этом в сессиях основных данных WWDC.
Но... где вы создаете контекст для очереди? В документации NSManagedObjectContext
состояние Apple:
[Контекст] предполагает, что владельцем по умолчанию является поток или очередь, которые его выделяют, - это определяется потоком, который вызывает его метод init. Поэтому вы не должны инициализировать контекст в одном потоке, а затем передавать его в другой поток.
Итак, теперь у нас есть идея NSManagedObjectContext
, которая должна знать, кто ее владелец. Я предполагаю, что это означает, что первая операция, которая должна быть выполнена в очереди, должна создать MOC и сохранить ссылку на нее для остальных операций, которые будут использоваться.
Правильно ли это? Единственная причина, по которой я не решаюсь, состоит в том, что в статье NSManagedObjectContext
говорится:
Вместо этого вы должны передать ссылку на постоянный координатор хранилища и получить принимающий поток/очередь для создания нового контекста, полученного из этого. Если вы используете NSOperation, вы должны создать контекст в основном (для последовательной очереди) или запустить (для параллельной очереди).
Теперь Apple, похоже, объединяет операции с очередями, которые планируют их выполнение. Это делает мою голову и заставляет меня задаться вопросом, действительно ли они хотят, чтобы вы просто создали новый MOC для каждой операции. Что мне не хватает?