CALayer.hitTest(CGPoint) EXC_BAD_ACCESS

In iPadOS, I'm building a tree on the screen using CALayer subclasses. Touching a visible node on the screen selects the node using CALayer.hitTest(CGPoint). This works reliably when I arrange the layers like this:

But when I rearrange the same CALayer objects to look like this, after an unpredictable number of touches on the a*b composite structure, the app dies with EXC_BAD_ACCESS:

Here is my code at the point of death. The LOOK HERE print statement just before invoking hitTest verifies that both layer and ksCGPoint have reasonable values.

Here is the stack trace:

Here is where the code actually dies in computeZ, which is called by CALayer.hitTest, which is invoked by VNode.touchesBegan, where VNode is a subclass of UIView.

Does anyone know what's going on here, or how to fix it?

  • Can you please copy the entire stack trace?

  • That is the entire stack trace for the thread that crashed the app.

  • Didn't know there was more. See below.

Add a Comment

Replies

When you move a VNode from one location to another, do you use UIView.addSubview() (or similar method) or do you use CALayer.addSubview() (or similar)?

If the latter, your probably corrupting the layer tree inadvertently as UIKit expects to always manage layers that are owned by views, and managing the tree at the Core Animation layer for those layers may confuse UIKit.

  • There is one VNode, which occupies most of the screen and never moves. Various CALayer subclass instances are added to it using VNode.layer.addSublayer. There is nothing exotic going on here, except for the moving of layers. That is how the flattened tree elements end up looking like that. The thing that is strange is that touching the flattened elements causes this problem sometime: not usually the first touch, might still work on the 50th, but probably the app has crashed before then.

Add a Comment

Thread 1 Queue : com.apple.main-thread (serial) #0 0x0000000187103a6c in computeZ(CALayer*, CALayer*, CA::Transaction*, CA::Vec2 const&, double) () #1 0x00000001871015c4 in -[CALayer hitTest:] () #2 0x0000000187103998 in hitTestSublayers(X::List<CALayer*>, CA::Vec2 const&, CALayerArray) () #3 0x0000000187101574 in -[CALayer hitTest:] () #4 0x0000000187103998 in hitTestSublayers(X::List<CALayer*>, CA::Vec2 const&, CALayerArray) () #5 0x0000000187101574 in -[CALayer hitTest:] () #6 0x0000000187103998 in hitTestSublayers(X::List<CALayer*>, CA::Vec2 const&, CALayerArray) () #7 0x0000000187101574 in -[CALayer hitTest:] () #8 0x0000000101013790 in VNode.touchesBegan(:with:) at /Users/steve/Desktop/DragginMath/DragginMath/DragginMath/View/VNode.swift:256 #9 0x0000000101013b34 in @objc VNode.touchesBegan(:with:) () #10 0x000000018587fed8 in _UIGestureEnvironmentUpdate () #11 0x000000018343182c in CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION () #12 0x0000000183402a64 in __CFRunLoopDoObservers () #13 0x00000001833fdfec in __CFRunLoopRun () #14 0x0000000183411240 in CFRunLoopRunSpecific () #15 0x00000001a3d27988 in GSEventRunModal () #16 0x0000000185c1141c in -[UIApplication _run] () #17 0x00000001859aab88 in UIApplicationMain () #18 0x0000000100fe39a0 in main at /Users/steve/Desktop/DragginMath/DragginMath/DragginMath/AppDelegate.swift:12 #19 0x00000001016dc3d0 in start () Thread 2#0 0x00000001bcfe3014 in __workq_kernreturn () Thread 4#0 0x00000001bcfe3014 in __workq_kernreturn () com.apple.uikit.eventfetch-thread (6)#0 0x00000001bcfe2aac in mach_msg_trap () #1 0x00000001bcfe307c in mach_msg () #2 0x00000001833f9d78 in __CFRunLoopServiceMachPort () #3 0x00000001833fe080 in __CFRunLoopRun () #4 0x0000000183411240 in CFRunLoopRunSpecific () #5 0x0000000184b1eefc in -[NSRunLoop(NSRunLoop) runMode:beforeDate:] () #6 0x0000000184b5e010 in -[NSRunLoop(NSRunLoop) runUntilDate:] () #7 0x0000000185b9086c in -[UIEventFetcher threadMain] () #8 0x0000000184b6bc0c in NSThread__start () #9 0x00000001dd679348 in _pthread_start ()