Сбой при использовании 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 и т. Д.
Если вы предоставите больше результатов такого расследования, вам будет легче определить следующие шаги.