Пользовательский интерфейс iPhone addSubview, вызывающий исключение параллелизма - PullRequest
3 голосов
/ 11 ноября 2009

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

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

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. Может быть, это как-то связано с добавлением чего-либо в представление, в то время как оно уже что-то добавляет? Есть идеи?

Ответы [ 5 ]

16 голосов
/ 11 ноября 2009

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

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

4 голосов
/ 11 ноября 2009

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

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

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

0 голосов
/ 09 марта 2010

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

0 голосов
/ 11 ноября 2009

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

0 голосов
/ 11 ноября 2009

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...