0
votes

XCode 9.1 iPhoneX simulator iPhone6 11.1.2

I have wasted days trying to track down a crash that appears to manifest in memory corruption (because it seems to be different each time).

I have narrowed it down to using a (simple) Container View Controller with Swipe Gesture Recognizer(s).

enter image description here

You can see the two (left and right) Swipe Gesture Recognizers and also two (Prev and Next) buttons in the Navigation Bar. The UIViewController has a simple UILabel.

The Gesture Recognizers are configured as:

enter image description here

The transition is performed by:

  private func addViewToLayout(view: UIView) {
    let views = ["view": view]

    view.translatesAutoresizingMaskIntoConstraints = false
    container.addSubview(view)

    container.addConstraints(
        NSLayoutConstraint.constraints(withVisualFormat: "V:|[view]|",
        options:NSLayoutFormatOptions.alignAllLeft, metrics:nil, views:views))
    container.addConstraints(
        NSLayoutConstraint.constraints(withVisualFormat: "H:|[view]|",
        options:NSLayoutFormatOptions.alignAllLeft, metrics:nil, views:views))
  }

  private func transition(direction: Direction = .left) {
    let controllerPrevious = childViewControllers.first

    if let controllerNext = storyboard?.instantiateViewController(
        withIdentifier: "Test") {
      addChildViewController(controllerNext)
      addViewToLayout(view: controllerNext.view)

      if let controllerPrevious = controllerPrevious {
        controllerNext.view.transform = startTransform(direction: direction)

        UIView.animate(withDuration: transitionDuration,
            animations: {
              controllerNext.view.transform = CGAffineTransform.identity
              controllerPrevious.view.transform =
                  self.endTransform(direction: direction)
            },
            completion: { (finished: Bool) in
              controllerPrevious.view.removeFromSuperview()
              controllerPrevious.removeFromParentViewController()
              controllerNext.didMove(toParentViewController: self)
            })
      }
    }
  }

The crashes can occur during/after a transition or after navigating away from the Container View Controller. The debugger usually ends up in the main thread with no meaningful stack trace.

enter image description here

The crashes are relative easy to cause, but do not always occur from the same actions, e.g. (logs obtained by running on a device):

EXC_BAD_ACCESS (SIGSEGV)
KERN_INVALID_ADDRESS at 0x4054600000000000
Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   libobjc.A.dylib                 0x0000000180f68428 objc_msgSend + 8
1   UIKit                           0x000000018b40dda4 -[UIView _layoutConstraintCleanup] + 204

or

EXC_CRASH (SIGABRT)
0x0000000000000000, 0x0000000000000000
EXC_CORPSE_NOTIFY
Thread 0 Crashed:
0   libsystem_kernel.dylib          0x000000018181d348 __pthread_kill + 8
1   libsystem_pthread.dylib         0x0000000181931344 pthread_kill$VARIANT$mp + 396
2   libsystem_c.dylib               0x000000018178cfb8 abort + 140
3   libsystem_malloc.dylib          0x0000000181863a08 nanozone_default_reader + 0

Note, the crashes do not happen if only the Buttons in the Navigation Bar are used.

Is there anything that can help isolate the cause of the crashes?

Do the Gesture Recognizers need to be fiddled with when releasing the current child view controller after the transition?

This question appears to have similar symptoms, but doesn't really have any useful suggestions.

Edit:

I have uploaded a project that exhibits the crash to Dropbox. Compile project, run, tap Next, use two-touch swipes left and right multiple times, tap Back, tap Next, repeat until crash. Sometimes crash is immediate, sometimes it might take 20 or more actions.

2
in your completion block in the transition - can you remove that part and see if the crash still happens? I feel like you might be running into a race condition and that's why the errors are inconsistent. (not at my dev mac or id test it more)solenoid
just for reference, there is an apple supplied method to do custom animated transitions developer.apple.com/documentation/uikit/…solenoid
@solenoid I tried removing removeFromParentViewController, and then didMove as well. Crash still happened.Matt
I have filed a bug 35792348. Maybe someone at Apple can figure out what is happening.Matt

2 Answers

0
votes

From the limited data you’ve provided, it looks like you have a memory smasher.

You should use the tools that Xcode provides to debug such problems and provide the results of that investigation. Use static analysis of your project. Run with ASan, NSZombies, GuardMalloc, etc.

If you provide more results from such investigation, it will be easier to help you figure out next steps.

0
votes

This may be simplistic, but I've run into problems with Interface Builder and 2 finger swipes. When I assign it 1 finger, it works fine, but it crashes on 2 finger.

If I leave it as 1 finger in IB and change it to 2 finger in viewDidLoad, my problem goes away.