Почему я должен создавать контекст в 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
}
Другие вопросы по тегам