Pergunta

Isso é realmente estranho ...

Eu corro meu aplicativo e, enquanto ele está abrindo e as visualizações estão construindo, eu recebo:

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

O rastreamento do código passa pelo seguinte:

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

Eu corri o jogo muito e muitas vezes e nunca vi isso, então de repente apareceu. O estranho é que não estou criando outros tópicos (que eu conheço) até depois Este código é chamado. Será mais fácil para mim depurar isso se alguém puder me dar alguma explicação do que pode estar sendo modificado enquanto estiver sendo acessado em uma UIView. Tem algo a ver com adicionar algo à visão enquanto já está adicionando algo, talvez? Alguma ideia?

Foi útil?

Solução

Não é uma exceção de simultaneidade. As exceções de mutação de enumeração acontecem quando algo (possivelmente dentro de um loop no mesmo segmento) altera a matriz/conjunto/dicionário que o loop está iterar.

Como AddSubView: está na pilha, meu palpite é que algo está tentando remover uma das subviews da UIView durante a construção.

Você está substituindo algum método que possa estar sendo executado? Como Addsubview ou possivelmente layoutSubviews? Se alguma delas estiver removendo subviews, isso causaria o problema.

Outras dicas

É possível que sua visão tenha uma subcamada em que você atribuiu o delegado para ser a visualização? Isso normalmente faria com que a visão seja recorrente infinitamente (bem, até atingir o limite da pilha) ao ligar _makeSubtreePerformSelector:withObject:withObject:copySublayers:, mas suponho que seja possível que tudo o que esteja tentando fazer aqui envolva mutação.

A razão é que é porque o UIView assume que, se o delegado de um calayer é uma UIView, esse calayer pertence ao UIView e à UIView faz parte da hierarquia. No entanto, se você criar sua própria calayer e atribuir o delegado para ser o UIView, o UIView acabará se chamando como parte da recursão.

Da documentação:

A enumeração é "segura" - o enumerador possui um guarda de mutação para que, se você tentar modificar a coleção durante a enumeração, uma exceção será levantada.

Basicamente, isso significa que você não tem permissão para adicionar/remover objetos a uma coleção (por exemplo, uma matriz) enquanto a enumra usando a enumeração rápida introduzida no Objective-C 2.0. Porque fazer isso tornará o guarda da mutação inválido.

No seu caso, a coleção está relacionada a uma hierarquia de visualizações. Se você deseja adicionar e/ou remover vistas a esta coleção específica, não use enumeração rápida.

Eu vi isso acontecer dentro de caligedores quando você tenta limpar uma propriedade durante o método -DealLoc do calayer, alterando apenas essa propriedade altera inadvertidamente uma propriedade visível da camada. Você pode verificar e ver se está de alguma forma fazendo algo que altera as propriedades de uma de suas opiniões durante o -Dealloc da mesma visão.

Eu bati no mesmo bug. Eu estava mudando a hierarquia de visualizações em um fio não-especial. Verifique se todas as modificações na visualização são executadas no thread principal.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top