que tienen un problema que es casi idéntico al problema descrito por esta persona aquí, pero no ha respondido a obtener:de Datos Básicos anidada logró contextos de objetos y puntos muertos frecuentes/congela
Aquí está el problema:
tengo una configuración MOC padre con NSPrivateQueueConcurrencyType y un conjunto coordinador de almacén persistente, tiene una configuración MOC niño con NSMainQueueConcurrencyType. La idea de que la mayor parte del trabajo arduo y largo se ahorre se puede hacer en el MOC privado, lo que libera al hilo principal del bloqueo de la IU. Desafortunadamente, parece que me encuentro con un par de situaciones que causan bloqueos.
Si el MOC secundario (en el hilo principal) realiza una búsqueda con NSFetchedResultsController, el contexto principal se envía a -executeFetchRequest: puede crear un interbloqueo. Ambas operaciones se realizan dentro del contexto de un performBlock: para sus respectivos MOC aunque los documentos parecen indicar que el uso de un tipo de concurrencia de subproceso principal MOC en el subproceso principal sin performBlock: está bien.
Parece que la cola privada está esperando en el bloqueo de PSCs que el contexto secundario en el hilo principal ya ha bloqueado. Parece que el contexto secundario (mientras mantiene el bloqueo de los PSC) está intentando enviar el sincronizador al contexto primario y, por lo tanto, ambos están esperando el uno al otro.
¿PriveQueue -> MainQueue es una configuración compatible? Parece que la mayoría de las personas todavía tienen el contexto principal en el hilo principal.
El hilo principal es el siguiente:
> #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
la pila de espera privada se ve así:
#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()
también escribe esto:
estoy empezando a pensar el problema es con NSFetchedResultsController que siempre está bloqueado en performFetch: cuando se producen estos bloqueos. La mayoría de las veces estará atascado intentando fallar en un objeto como resultado de pedir su nombre de sección. Como prueba, traté de reproducir lo que hace el FRC y realicé el executeFetchRequest: y luego repetí los resultados preguntando a cada objeto por su nombre de sección. Y esto no causa un punto muerto. Si dejo el FRC para realizar la función Obtener: después de hacer mi prueba, todavía se estancará allí. Estoy 99% seguro de que el FRC tiene un problema de sincronización con contextos anidados.
Pregunta: ¿Alguien sabe por qué ocurre este problema? sabes como resolverlo? ¿Es esto un error?
¿Envías '-executeFetchRequest' al contexto principal? ¿Por qué? –
Como el hilo de fondo (MOC de fondo/padre) está sincronizando los datos hacia un servidor, estoy haciendo una solicitud de búsqueda para descubrir qué objetos necesitan sincronizarse. – thejaz
+1 mismo problema. Para contextos anidados, estoy usando contextos de almacenamiento principal y de raíz de magicalrecord. Antes de llamar a FRC performFetch, inicié una solicitud de sincronización al servidor. El código se congela en performFetch. – angelokh