我使用AVSpeechSynthesizer来说文本,在使用它大约200次之后,一些奇怪的行为正在发生(在macOS模拟器中,也在iPad模拟器中(在大约200个调用(synthesizer.speak(utterance)
(之后,一切都按预期工作,它突然进入了他的AVSpeechSynthesizerDelegate的didCancel
方法((,并永远停止工作!,即使didCancel
再也没有被调用过,或者任何其他委托方法都被称为synthesizer.speak(utterance)
。
我曾尝试将合成器引用分配给didCancel
方法中的一个新的AVSpeechSynthesizer实例,但它对它没有影响,在didCancel
方法累积后,唯一"让它回来"的就是再次运行应用程序,然后在使用synthesizer-speak方法进行大约200次调用后,它再次崩溃。这是我的代码:
var synthesizer:AVSpeechSynthesizer! = AVSpeechSynthesizer()
override func viewDidLoad() {
synthesizer.delegate = self
}
func speakText(utterance: AVSpeechUtterance ) {
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback, mode: .default, options: .mixWithOthers)
try AVAudioSession.sharedInstance().setActive(true, options: .notifyOthersOnDeactivation)
} catch {
print("audioSession properties weren't set because of an error.")
}
synthesizer.speak(utterance)
print("speak now (utterance.speechString)")
}
func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didCancel utterance: AVSpeechUtterance) {
print(" AVSpeechSynthesizerDelegate cancel")
}
我设法解决了这个问题,我从if else
语句中调用了speakText(utterance: AVSpeechUtterance)
方法,该语句根据需要更改话语文本,然后调用每个块中的函数。(在if
和else
块中(
我所做的是将话语置于块之外,并将其分配给nil:var utterance:AVSpeechUtterance
。那么在CCD_ 12块中,我已经为其分配了适当的值。
然后在块之外,我检查了值是否已设置,以及它是否已设置(不是零(。所有这些功能在一个由同步全局线程块触发的函数中都发生了扭曲。像这样
DispatchQueue.global(qos: .userInteractive).sync{ [unowned self] in
self.userDidEnterText(text: text)
}
希望这种处理方式能给将来面临这个问题的人一个想法或方向。