Почему я должен создавать контекст в main для последовательной очереди и в start для параллельной очереди?
В Руководстве по программированию Core Data есть тема о шаблоне ограничения потока, и там говорится, что
Вы должны создать управляемый контекст в потоке, в котором он будет использоваться. Если вы используете NSOperation, обратите внимание, что его метод init вызывается в том же потоке, что и вызывающая сторона. Поэтому нельзя создавать контекст управляемого объекта для очереди в методе init очереди, в противном случае он связан с потоком вызывающей стороны. Вместо этого вы должны создать контекст в main (для последовательной очереди) или start (для параллельной очереди).
Я просто не могу понять, почему это? В чем разница?
2 ответа
Это говорит о том, почему довольно ясно в документации, которую вы цитировали. Операции init
метод работает в потоке вызывающих в то время как работа, которая происходит в main
метод может выполняться в другом потоке.
Поскольку вы не можете совместно использовать контексты управляемого объекта между потоками, вам необходимо создать его в том же потоке, в котором вы будете его использовать. Таким образом, если вы используете его в операции, вам нужно убедиться, что контекст создан в том же потоке, в котором выполняется операция.
Причина, по которой последовательные операции создают контекст в main, заключается в том, что они запускают стандартные start
реализация при переопределении start
когда вы реализуете параллельные операции.
Подробнее о том, как работают параллельные операции, вы можете прочитать в Руководстве по программированию параллелизма (совет: ищите "start")
Дэвид прав.
Документация говорит, что если, например, у вас есть NSOperation
подкласс называется MyOperation
и вы отменяете init
метод, подобный следующему
- (id)init
{
if(self = [super init]) {
// your context here
}
return self;
}
Затем, если вы создадите эту операцию в основном потоке, как
MyOperation* op = // alloc-init
контекст, который вы создали, связан с основным потоком, а НЕ с потоком, в который входит операция.
Странные вещи могут произойти, когда вы выполняете изменения (удаление, обновление и т. Д.) В управляемых объектах, поскольку вы изменяете их в фоновом режиме, но получаете доступ к контексту, который находится в основном потоке.
Override main
вместо этого и создайте контекст там:
- (void)main
{
// your context here
}