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