【问题标题】:UIFeedback Haptic Engine called more times than was activatedUIFeedback Haptic Engine 调用次数多于激活次数
【发布时间】:2016-10-26 23:49:29
【问题描述】:

我将UIFeedback Haptic Engineswift 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:]

【问题讨论】:

    标签: ios swift ios10 uifeedbackgenerator


    【解决方案1】:

    UIImpactFeedbackGenerator 不是线程安全的,因此请确保您正在同步调用generator.impactOccurred(),而不是在dispatch_async 或另一个异步线程中。

    【讨论】:

    • 这是正确的答案,但说不要在 dispatch_async 中使用它似乎有点误导。我认为你的意思是他应该只从一个线程中调用它。他实际上可能需要调用 dispatch_async 才能到达那个单线程。
    • 嗨,你能说明一下如何做到这一点吗?
    • @KelvinFok DispatchQueue.main.async { }
    【解决方案2】:

    iOS 11.* 上调用 generator.impactOccurred() 会崩溃。您需要在主线程async 上调用它。

    let generator = UIImpactFeedbackGenerator(style: style)
    generator.prepare()
    
    DispatchQueue.main.async {
       generator.impactOccurred()
    }
    

    【讨论】:

    • 在 iOS 13 中也崩溃了,我认为我们可以说比 iOS 11 更好
    【解决方案3】:

    只是为了完成已经给出的答案:您想要做的是拥有一个 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()
            }
        }
    
    }
    

    这几乎解决了我们在生产中的相关崩溃问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-04
      • 1970-01-01
      • 1970-01-01
      • 2016-09-08
      • 2015-09-24
      • 1970-01-01
      • 2016-05-12
      相关资源
      最近更新 更多