UIFeedback Haptic Engine вызывался больше раз, чем был активирован
Я использую UIFeedback Haptic Engine
с быстрым 2.3 вроде:
let generator = UINotificationFeedbackGenerator()
generator.notificationOccurred(.Warning)
а также
let generator = UIImpactFeedbackGenerator(style: .Heavy)
generator.impactOccurred()
Сегодня я получил новую ошибку, подобную этой, и не смог найти проблему. Есть ли у вас какие-либо идеи?
UIFeedbackHapticEngine _deactivate] called more times than the feedback engine was activated
Подробности:
Fatal Exception: NSInternalInconsistencyException
0 CoreFoundation 0x1863e41c0 __exceptionPreprocess
1 libobjc.A.dylib 0x184e1c55c objc_exception_throw
2 CoreFoundation 0x1863e4094 +[NSException raise:format:]
3 Foundation 0x186e6e82c -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:]
4 UIKit 0x18cc43fb8 -[_UIFeedbackEngine _deactivate]
5 UIKit 0x18cad781c -[UIFeedbackGenerator __deactivateWithStyle:]
2 ответа
UIImpactFeedbackGenerator
не является потокобезопасным, поэтому убедитесь, что вы звоните generator.impactOccurred()
синхронно, а не в dispatch_async
или в другом асинхронном потоке.
Призвание generator.impactOccurred()
произойдет сбой на iOS 11. *. Вы должны назвать это в главном потоке async
,
let generator = UIImpactFeedbackGenerator(style: style)
generator.prepare()
DispatchQueue.main.async {
generator.impactOccurred()
}
Просто чтобы завершить ответ, который уже был дан: вам нужно либо иметь OperationQueue, либо DispatchQueue, которые всегда будут использоваться для вызова функций FeedbackGenerator. Имейте в виду, что для вашего варианта использования вам, возможно, придется выпустить генераторы, но минимальный пример:
class HapticsService {
private let hapticsQueue = DispatchQueue(label: "dev.alecrim.hapticQueue", qos: .userInteractive)
typealias FeedbackType = UINotificationFeedbackGenerator.FeedbackType
private let feedbackGeneator = UINotificationFeedbackGenerator()
private let selectionGenerator = UISelectionFeedbackGenerator()
func prepareForHaptic() {
hapticsQueue.async {
self.feedbackGeneator.prepare()
self.selectionGenerator.prepare()
}
}
func performHaptic(feedback: FeedbackType) {
hapticsQueue.async {
self.feedbackGeneator.notificationOccurred(feedback)
}
}
func performSelectionHaptic() {
hapticsQueue.async {
self.selectionGenerator.selectionChanged()
}
}
}
Это в значительной степени решило связанные с этим сбои в производстве.