Обновление: Как отмечает @adib в комментарии, подход к сериализованному доступу к контексту управляемого объекта изменился в iOS 9 и MacOS X 10.11. NSConfinementConcurrencyType
, стратегия ограничения потока, теперь устарела в пользу NSPrivateQueueConcurrencyType
и NSMainQueueConcurrencyType
. Другими словами, прекратите использовать потоки для одновременного доступа к объектам Core Data и вместо этого начните использовать GCD. Вы должны использовать либо основную очередь отправки, либо ту, что связана с MOC, в зависимости от того, как вы настраиваете MOC, а не очередь вашего собственного создания. Это легко сделать, используя методы NSManagedObject -performBlock:
или -performBlockAndWait:
.
Краткий ответ: Использование очереди последовательной отправки может обеспечить сериализованный доступ к контексту управляемого объекта, и это приемлемый способ реализации стратегии «ограничения потока», даже если GCD может фактически использовать несколько потоков.
Более длинный ответ:
Принятый ответ на этот вопрос с использованием очередей GCD обеспечивает
что новый контекст создается в каждом потоке, но не указывает на
необходимость сделать это.
Важно помнить, что вы должны избегать изменения контекста управляемого объекта из двух разных потоков одновременно . Это может привести контекст в противоречивое состояние, и ничего хорошего из этого не выйдет. Таким образом, вид очереди отправки, которую вы используете, важен: параллельная очередь отправки позволяет одновременно выполнять несколько задач, и если они обе используют один и тот же контекст, у вас будут проблемы. Если вы используете очередь последовательной отправки, с другой стороны, две или более задач могут выполняться в разных потоках, но задачи будут выполняться по порядку, и одновременно будет выполняться только одна задача. Это очень похоже на выполнение всех задач в одном потоке, по крайней мере, в том, что касается поддержания согласованности контекста.
См. этот вопрос и ответ для более подробного объяснения.
Вот как Core Data всегда работали. Раздел Параллельность с базовыми данными в Руководстве по программированию базовых данных дает советы о том, как действовать, если вы решили использовать один контекст в нескольких потоках. В основном речь идет о необходимости быть очень осторожным, чтобы блокировать контекст каждый раз, когда вы получаете к нему доступ. Однако смысл всей этой блокировки заключается в том, чтобы два или более потока не пытались использовать контекст одновременно. Использование сериализованной очереди отправки позволяет достичь той же цели: поскольку одновременно выполняется только одна задача в очереди, нет никаких шансов, что две или более задач будут пытаться использовать контекст одновременно.