Сбой при использовании Swipe Gesture Recognizer с пользовательским контроллером представления контейнера

XCode 9.1 iPhoneX симулятор iPhone6 ​​11.1.2

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

Я сузил его до использования (простого) Контейнерного Контроллера Представления с Распознавателем Жестов Размаха.

Вы можете увидеть две (левые и правые) устройства распознавания жестов, а также две кнопки ("Предыдущая" и "Следующая") на панели навигации. UIViewController имеет простой UILabel,

Распознаватели жестов настраиваются следующим образом:

Переход осуществляется:

  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)
            })
      }
    }
  }

Сбои могут произойти во время / после перехода или после перехода от Контейнера Представления Контейнера. Отладчик обычно заканчивается в основном потоке без какой-либо значимой трассировки стека.

Сбои относительно легко вызвать, но они не всегда происходят из-за одних и тех же действий, например (журналы, полученные при запуске на устройстве):

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

или же

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

Обратите внимание, что сбои не происходят, если используются только кнопки на панели навигации.

Есть ли что-нибудь, что может помочь изолировать причину сбоев?

Нужно ли возиться с распознавателями жестов при освобождении текущего дочернего контроллера представления после перехода?

У этого вопроса, похоже, есть похожие симптомы, но на самом деле нет никаких полезных предложений.

Редактировать:

Я загрузил проект, который показывает сбой в Dropbox. Скомпилируйте проект, запустите, нажмите "Далее", несколько раз проведите двумя касаниями влево и вправо, нажмите "Назад", нажмите "Далее", повторяйте до сбоя. Иногда сбой происходит немедленно, иногда может потребоваться 20 или более действий.

2 ответа

Это может быть упрощенно, но я столкнулся с проблемами с Интерфейсным Разработчиком и двумя пальцами. Когда я назначаю ему 1 палец, он работает нормально, но он падает на 2 пальца.

Если я оставлю это как 1 палец в IB и поменяю его на 2 пальца в viewDidLoad, моя проблема исчезнет.

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

Вы должны использовать инструменты, которые предоставляет XCode, для отладки таких проблем и предоставления результатов этого исследования. Используйте статический анализ вашего проекта. Запускать с ASan, NSZombies, GuardMalloc и т. Д.

Если вы предоставите больше результатов такого расследования, вам будет легче определить следующие шаги.

Другие вопросы по тегам