我使用UIFeedback Haptic Engine
与swift 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:]
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()
}
}
}
这基本上解决了我们在生产中相关的崩溃问题。