2013-05-04 4 views
4

У меня есть приложение OSX, где я использую настройку NSManagedObjectContext для родительского/дочернего объекта. У ребенка MOC есть NSPrivateQueueConcurrencyType и тот, который я использую в первую очередь. Родитель устанавливается равным NSMainQueueConcurrencyTypeNSManagedObjectContext performBlockAndWait вызывает тупик при вызове из двух потоков

Когда я звоню performBlockAndWait от контекста ребенка от фонового потока в то же время, как она вызывается из основного потока я получаю тупик - semaphore_wait_trap. Приостановка отладчика показывает, что оба потока застревают в performBlockAndWait

Как я могу обойти это? Я думал, что этот метод был разработан именно для этой ситуации и будет просто помещать блоки в частную очередь контекста, а затем возвращаться соответствующим образом?

ответ

2

Я работал над этим, создав очередную очередь, а затем выполнил все мои вызовы с выполнением вызова через это, чтобы убедиться, что они не будут вступать друг в друга. Честно говоря, я не уверен, что это хорошая практика, но она решила проблему для моей конкретной ситуации.

1

NSManagedObjectContext по-прежнему не является потокобезопасным, даже с частными типами параллелизма.

performBlock: and performBlockAndWait: только убедитесь, что операции блока выполняются в очереди, указанной для контекста.

Вы все равно можете получить взаимоблокировки с помощью executeBlockAndWait :, поскольку он заблокирует текущий исполняемый поток, пока он не вернется. Что происходит внутри performBlockAndWait :? Возможно, что-то, что требует доступа к основному потоку, поэтому он зашел в тупик.

Можете ли вы использовать performBlock: вместо этого?

+0

hmm Я могу попробовать и переключить свой код на выполнение. Блокировать да, определенно будет немного дольше с обратными вызовами и т. Д., Но вполне возможно, я уверен. Итак, используя этот метод, блоки будут выполняться в потокобезопасном режиме? –

+0

performBlock and performBlockAndWait просто убедитесь, что блок, который вы передаете в них, выполняется в правильной очереди, связанной с контекстом управляемого объекта. Так что да, ваши блоки будут выполняться поточно-безопасным образом в контексте - разница в семантике вашего кода и если вам нужно заблокировать и ждать завершения блока. Я всегда стремился сначала использовать executeBlock и использовать executeBlockAndWait, если бы мне пришлось по какой-то причине. См. Http://developer.apple.com/library/mac/#releasenotes/DataManagement/RN-CoreData/index.html. – bandejapaisa

Смежные вопросы