Pregunta

Esto es realmente extraño ...

Ejecuto mi aplicación, y mientras se abre y las vistas están construyendo, obtengo:

Collection <CALayerArray: 0x124650> was mutated while being enumerated.

La traza del código pasa por lo siguiente:

main
UIApplicationMain
-[UIApplication _run]
CFRunLoopRunInMode
CFRunLoopRunSpecific
_UIApplicationHandleEvent
-[UIApplication sendEvent:]
-[UIApplication handleEvent:withNewEvent:]
-[UIApplication _runWithURL:sourceBundleID:]
-[UIApplication _performInitilizationWithURL:sourceBundleID:]
-[AppDelegate applicationDidFinishLaunching:]
+[Controller initializeController] //This is my own function
    [window addSubview: pauseMenuController.view] //This is the last point of my code it goes through
-[UIView(Hierarchy) addSubview:]
-[UIView(Internal) _addSubview:positioned:relativeTo:]
-[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:]
-[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:]
-[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:]
_NSFastEnumerationMutationHandler
objc_exception_throw

He ejecutado el juego mucho, muchas veces y nunca he visto esto, y de repente apareció. Lo extraño es que no estoy creando ningún otro hilo (que sepa) hasta que después Todo este código se llama. Será más fácil para mí depurar esto si alguien puede darme una explicación de lo que podría modificarse mientras se accede en una vista UIVIEW. ¿Tiene algo que ver con agregar algo a la vista mientras ya está agregando algo, tal vez? ¿Algunas ideas?

¿Fue útil?

Solución

No es una excepción de concurrencia. Las excepciones de mutación de enumeración ocurren cuando algo (posiblemente dentro de un bucle en el mismo hilo) cambia la matriz/set/diccionario que el bucle está iterando.

Desde AddSubView: está en la pila, supongo que algo está tratando de eliminar una de las subvistas de UIView durante la construcción.

¿Está anulando algún método que pueda estar ejecutándose? ¿Como AddSubView o Posiblemente LightSubViews? Si alguno de estos está eliminando las subvistas, esto causaría el problema.

Otros consejos

¿Es posible que su punto de vista tenga un subcapitán donde asignó al delegado para ser la vista? Esto normalmente causaría la opinión de recurrir infinitamente (bueno, hasta que alcance el límite de la pila) al llamar _makeSubtreePerformSelector:withObject:withObject:copySublayers:, pero supongo que es posible que lo que sea que esté tratando de hacer aquí implique mutación.

La razón por la que esto es así es porque UIView supone que si el delegado de un calayer es una vista UIVIEW, entonces que Calayer pertenece a UIVIEW y el UIVIEW es parte de la jerarquía. Sin embargo, si crea su propio calayer y asigna el delegado para que sea el UIVIEW, el UIView terminará llamándose a sí mismo como parte de la recursión.

De la documentación:

La enumeración es "segura": el enumerador tiene un protector de mutación para que si intenta modificar la colección durante la enumeración, se plantea una excepción.

Básicamente, esto significa que no puede agregar/eliminar objetos a una colección (digamos una matriz) mientras lo enumera utilizando la enumeración rápida introducida en Objective-C 2.0. Porque hacerlo hará que el guardia de mutación sea inválido.

En su caso, la colección está relacionada con una jerarquía de vista. Si desea agregar y/o eliminar vistas a esta colección en particular, no use una enumeración rápida.

He visto que esto sucede dentro de Calayers cuando intenta borrar una propiedad durante el método de calayer -Dealloc, solo cambiando esa propiedad inadvertidamente altera una propiedad visible de la capa. Puede verificar y ver si de alguna manera está haciendo algo que cambie las propiedades de una de sus puntos de vista durante el -DealLoc de esa misma vista.

Me topé con el mismo error. Estaba mutando la jerarquía de vista en un hilo no principal. Asegúrese de que todas las modificaciones a la vista se realicen en el hilo principal.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top