iPhone пользовательский интерфейс addSubview, вызывая исключение параллелистики

StackOverflow https://stackoverflow.com/questions/1711700

  •  19-09-2019
  •  | 
  •  

Вопрос

Это действительно странно ...

Я запускаю свое приложение, и пока оно открывается, и представления строятся, я получаю:

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

Трассировка кода проходит следующее:

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

Я запускал игру много -много -много раз, и я никогда не видел этого, а затем внезапно выскочил. Странно то, что я не создаю никаких других потоков (о которых я знаю) до тех пор, пока после Этот код все вызывается. Мне будет легче отладить это, если кто -то сможет дать мне некоторое объяснение того, что может быть изменено, когда к нему доступ к Uiview. Имеет ли это какое -то отношение к добавлению чего -то в вид, в то время как это уже что -то добавляет, может быть,? Любые идеи?

Это было полезно?

Решение

Это не исключение параллелизма. Исключения мутации перечисления происходят, когда что -то (возможно, внутри цикла в том же потоке) меняет массив/набор/словарь, который цикл является итерационным.

Поскольку addsubview: находится в стеке, я предполагаю, что что -то пытается удалить один из подвесителей Uiview во время строительства.

Вы переопределяете какие -либо методы, которые могут быть запущены? Как addSubview или, возможно, MayoutoutSubviews? Если что -то из них удаляет подвесители, то это вызовет проблему.

Другие советы

Возможно ли, что у вашего взгляда есть подваритель, в котором вы назначили делегат, чтобы он был представлением? Это обычно приведет к тому, что представление будет бесконечно повторяться (ну, пока он не достигнет предела стека) при вызове _makeSubtreePerformSelector:withObject:withObject:copySublayers:, но я полагаю, что возможно, что все, что он пытается делать прямо здесь, включает в себя мутацию.

Причина, по которой это заключается в том, что Uiview предполагает, что если делегат Calayer является Uiview, то этот Calayer принадлежит Uiview, а Uiview является частью иерархии. Однако, если вы создаете свой собственный Calayer и назначите делегата быть Uiview, Uiview в конечном итоге призовет себя как часть рекурсии.

Из документации:

Перечисление является «безопасным» - перечислитель имеет охрану мутации, так что, если вы попытаетесь изменить коллекцию во время перечисления, поднимается исключение.

По сути, это означает, что вам не разрешено добавлять/удалять объекты в коллекцию (скажем, массив), в то время как вы перечисляете его, используя быстрое перечисление, представленное в Objective-C 2.0. Потому что это сделает охранник мутации недействительным.

В вашем случае коллекция связана с иерархией представления. Если вы хотите добавить и/или удалить представления в эту конкретную коллекцию, не используйте быстрое перечисление.

Я видел, как это произошло в Calayeres, когда вы пытаетесь очистить свойство во время метода -диаллока Calayer, только изменяя это свойство случайно изменяет видимое свойство слоя. Вы можете проверить и посмотреть, делаете ли вы что -то что -то, что меняет свойства одного из ваших взглядов во время -dealloc того же взгляда.

Я натолкнулся на ту же ошибку. Я мутировал иерархию представления в нити, не относящейся к мэрию. Убедитесь, что все модификации представления выполняются в основном потоке.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top