Базовые контексты вложенных управляемых объектов и частые тупики / зависания

I have a problem that is almost identical to the problem described by this person here, but it hasn't get answered:

http://www.cocoabuilder.com/archive/cocoa/312683-core-data-nested-managed-object-contexts-and-frequent-deadlocks.html#312683

Here is the problem:

У меня есть родительская настройка MOC с NSPrivateQueueConcurrencyType и постоянный набор координаторов хранилища, у него есть дочерняя настройка MOC с NSMainQueueConcurrencyType. Идея, заключающаяся в том, что большую часть долгой и трудоемкой работы можно сохранить на частном MOC, освобождает основной поток от блокировки пользовательского интерфейса. К сожалению, я, кажется, сталкиваюсь с парой ситуаций, которые вызывают тупики.

Если дочерний MOC (в основном потоке) выполняет выборку с помощью NSFetchedResultsController, родительскому контексту отправляется -executeFetchRequest: он может создать взаимоблокировку. Обе операции выполняются в контексте executeBlock: для их соответствующих MOC, хотя документы, по-видимому, указывают, что использование типа MOC с параллелизмом основного потока в основном потоке без executeBlock: нормально.

Похоже, что частная очередь ожидает блокировки PSC, которую дочерний контекст в основном потоке уже заблокировал. Похоже, что дочерний контекст (удерживая блокировку PSC) пытается диспетчеризировать_синхронизацию с родительским контекстом, и поэтому они оба ждут друг друга.

Есть PriveQueue - & gt; MainQueue поддерживаемая конфигурация? Кажется, у большинства людей все еще есть родительский контекст в главном потоке.

Основной поток выглядит так:

> #0    0x960f6c5e in semaphore_wait_trap ()
> #1    0x04956bb5 in _dispatch_thread_semaphore_wait ()
> #2    0x04955c8f in _dispatch_barrier_sync_f_slow ()
> #3    0x04955dea in dispatch_barrier_sync_f ()
> #4    0x01797de5 in _perform ()
> #5    0x01798547 in -[NSManagedObjectContext(_NestedContextSupport) newValuesForObjectWithID:withContext:error:] ()
> #6    0x0176416b in _PFFaultHandlerLookupRow ()
> #7    0x01763f97 in -[NSFaultHandler fulfillFault:withContext:forIndex:] ()
> #8    0x01763b75 in _PF_FulfillDeferredFault ()
> #9    0x017639f2 in _sharedIMPL_pvfk_core ()
> #10    0x017681a0 in _pvfk_11 ()
> #11    0x0001b322 in -[FBUser sectionName] at /Users/mlink/Code/x/x/FBUser.m:62
> #12    0x011a8813 in _NSGetUsingKeyValueGetter ()
> #13    0x017a0652 in -[NSManagedObject valueForKey:] ()
> #14    0x011ab8d5 in -[NSObject(NSKeyValueCoding) valueForKeyPath:] ()
> #15    0x01851f72 in -[NSFetchedResultsController(PrivateMethods) _sectionNameForObject:] ()
> #16    0x01853af6 in -[NSFetchedResultsController(PrivateMethods) _computeSectionInfo:error:] ()
> #17    0x01850ea6 in -[NSFetchedResultsController performFetch:] ()
> #18    0x0003a4fc in __62-[SYFriendsTableViewController updateFetchedResultsController]_block_invoke_0 ()
> #19    0x01797af3 in developerSubmittedBlockToNSManagedObjectContextPerform ()
> #20    0x049554f0 in _dispatch_main_queue_callback_4CF ()
> #21    0x01b3e833 in __CFRunLoopRun ()
> #22    0x01b3ddb4 in CFRunLoopRunSpecific ()
> #23    0x01b3dccb in CFRunLoopRunInMode ()
> #24    0x023d6879 in GSEventRunModal ()
> #25    0x023d693e in GSEventRun ()
> #26    0x0089aa9b in UIApplicationMain ()
> #27    0x00002656 in main at /Users/mlink/Code/x/x/main.mm:16

стек частных очередей выглядит так:

#0    0x960f8876 in __psynch_mutexwait ()
#1    0x97e9e6af in pthread_mutex_lock ()
#2    0x0172ec22 in -[_PFLock lock] ()
#3    0x0172ebfa in -[NSPersistentStoreCoordinator lock] ()
#4    0x01746a8c in -[NSManagedObjectContext(_NSInternalAdditions) lockObjectStore] ()
#5    0x01745030 in -[NSManagedObjectContext executeFetchRequest:error:] ()
#6    0x0009d49f in -[NSManagedObjectContext(Additions) executeFetchRequest:] at /Users/mlink/Code/objc/C/C/NSManagedObjectContext+Additions.m:44
#7    0x0002177f in +[FBUser usersForFbids:inManagedObjectContext:] at /Users/mlink/Code/x/x/FBUser.m:435
#8    0x00021fc0 in __77+[FBUser updateUserFromGraphValues:inManagedObjectContext:completionHandler:]_block_invoke_0 at /Users/mlink/Code/x/x/FBUser.m:461
#9    0x0180f9f3 in developerSubmittedBlockToNSManagedObjectContextPerform_privateasync ()
#10    0x04954ecf in _dispatch_queue_drain ()
#11    0x04954d28 in _dispatch_queue_invoke ()
#12    0x049544af in _dispatch_worker_thread2 ()
#13    0x97ea1b24 in _pthread_wqthread ()
#14    0x97ea36fe in start_wqthread ()

He also writes this:

Я начинаю думать, что проблема в NSFetchedResultsController, который всегда застревает в executeFetch: когда возникают эти взаимоблокировки. Большую часть времени он застревает, пытаясь ошибиться в объекте в результате запроса его имени раздела. В качестве теста я попытался воспроизвести то, что делает FRC, и выполнил executeFetchRequest: а затем перебрал результаты, запрашивая у каждого объекта имя раздела. И это не вызывает тупика. Если я уйду из FRC, чтобы выполнить executeFetch: после того, как я выполню свой тест, он все равно останется там. Я на 99% уверен, что у FRC есть проблема синхронизации с вложенными контекстами.

Question: Does anybody know why this problem occurs? Do you know how to solve it? Is this a bug?

Ответы на вопрос(7)

Ваш ответ на вопрос