iPhone UI addSubview导致并发异常

Eli*_*Eli 3 iphone objective-c nsexception

这真奇怪......

我运行我的应用程序,当它打开并且视图正在构建时,我得到:

Collection <CALayerArray: 0x124650> was mutated while being enumerated.
Run Code Online (Sandbox Code Playgroud)

代码跟踪经历以下内容:

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
Run Code Online (Sandbox Code Playgroud)

我经常玩很多很多次游戏而且我从来没有看过这个,然后它突然出现了.奇怪的是,我不是创建任何其他线程(据我所知),直到之后的代码都被调用.如果有人可以给我一些解释在UIView中访问时可能会被修改的内容,我会更容易调试这个.它是否与视图中添加内容有关,而它已经添加了一些内容,可能吗?有任何想法吗?

Lil*_*ard 17

您的视图是否有可能将委托指定为视图的子图层?这通常会导致视图在调用时无限递归(好吧,直到它达到堆栈限制)_makeSubtreePerformSelector:withObject:withObject:copySublayers:,但我认为无论它在这里尝试做什么都涉及到突变.

之所以如此,是因为UIView假设如果CALayer的委托是UIView,那么CALayer属于UIView,而UIView是层次结构的一部分.但是,如果您创建自己的CALayer并将委托指定为UIView,则UIView最终会将自身称为递归的一部分.

  • Kevin对UIView层次结构重新委托的解释帮助我解决了一个切线问题:我添加了CALayer作为视图层的子层,并将控制器分配为委托。尽管在viewDidUnload / dealloc上我无效/释放了子层之前的视图,但我还是在_makeSubtreePerform ... copySublayers上崩溃了。解决的办法是在使任何内容无效之前删除子层。大概这阻止了作为委托的控制器调用已发布的子层。 (2认同)