Domanda

Questo è davvero strano ...

corro la mia app, e mentre si sta aprendo e il punto di vista stanno costruendo ottengo:

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

Il codice trace passa attraverso il seguente:

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

Ho eseguito i lotti di gioco e un sacco e un sacco di volte e non ho mai visto questo, poi improvvisamente spuntato. La cosa strana è che non sto creando eventuali altri thread (che io sappia) fino a dopo questo codice tutto viene chiamato. Sarà più facile per me, per il debug di questo se qualcuno mi può dare qualche spiegazione di ciò che potrebbe essere sempre modificato mentre è in corso l'accesso in un UIView. Ha qualcosa a che fare con l'aggiunta di qualcosa alla vista, mentre è già l'aggiunta di qualcosa, forse? Tutte le idee?

È stato utile?

Soluzione

Non è un'eccezione concorrenza. eccezioni Enumeration mutazione si verificano quando qualcosa (forse all'interno di un ciclo nello stesso thread) cambia la matrice / set / dizionario che il ciclo è iterazione.

Dal addSubview:. È in pila, la mia ipotesi è che qualcosa sta cercando di rimuovere una delle subviews del UIView durante la costruzione

Stai sovrascrivendo qualsiasi metodi che possono essere sempre run? Come addSubview o forse layoutSubviews? Se uno di questi è la rimozione subviews, allora questo potrebbe causare il problema.

Altri suggerimenti

E 'possibile che la visualizzazione ha un sottolivello in cui si è assegnato il delegato per essere il punto di vista? Ciò normalmente causare la visualizzazione per recurse infinitamente (o meglio, fino a quando non ha colpito il limite stack) quando si chiama _makeSubtreePerformSelector:withObject:withObject:copySublayers:, ma suppongo che sia possibile che tutto ciò che sta cercando di fare proprio qui coinvolge mutazione.

La ragione per questo è così perché UIView presuppone che se delegato del CALayer è un UIView, allora CALayer appartiene al UIView e UIView è parte della gerarchia. Tuttavia, se si crea il proprio CALayer e assegnare il delegato per essere l'UIView, l'UIView finirà che si fa chiamare come parte della ricorsione.

Dalla documentazione:

L'enumerazione è “sicuro” -la enumeratore ha una guardia mutazione in modo che se si tenta di modificare la raccolta durante l'enumerazione, viene sollevata un'eccezione.

In pratica, questo significa che non ti è permesso di aggiungere / rimuovere gli oggetti a una raccolta (diciamo un array), mentre si sta enumerazione utilizzando l'enumerazione veloce introdotto in Objective-C 2.0. perché così facendo renderà l'invalido guardia mutazione.

Nel vostro caso, la collezione è legata a una gerarchia vista. Se si desidera aggiungere e / o rimuovere viste per questa particolare collezione, non utilizzare l'enumerazione veloce.

Ho visto questo accadere entro CALayers quando si tenta di cancellare una proprietà durante il metodo -dealloc del CALayer, cambiando solo che la proprietà altera inavvertitamente una proprietà visibile del livello. Si poteva controllare e vedere se si sta in qualche modo facendo qualcosa che cambia le proprietà di uno dei vostri punti di vista durante il -dealloc dello stesso punto di vista.

mi ha colpito sullo stesso bug. Stavo mutando la gerarchia vista su un filo non principale. Assicurarsi che tutte le modifiche alla visualizzazione vengono eseguite sul thread principale.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top