DispatchSemaphore 不等待

问题描述 投票:0回答:1

在我的命令行应用程序中,DispatchSemaphore 不会等待,尽管初始化为零,通过“等待”递减并通过“信号”递增。我不想使用 RunLoop.main.run()。

import Foundation
import AVFoundation

var synthesizer = AVSpeechSynthesizer()
let sema = DispatchSemaphore(value: 0)

func say(_ line: String) {
    let utterance = AVSpeechUtterance(string: line)
    synthesizer.speak(utterance)
    sema.signal() // increment
}

say("hello")
sema.wait()  // decrement
//RunLoop.main.run()
swift command-line-interface dispatchsemaphore
1个回答
0
投票

AVSpeechSynthesizer.speak(_:)
记录仅“将您指定的话语[添加]到语音合成器的队列中”;合成器不一定立即开始说话,
speak(_:)
调用也不会等到合成器完成说话后再返回。

实际上,

synthesizer.speak(utterance)
会立即返回,这会立即向您的信号量发出信号。如果这是您的全部代码并且您将其作为脚本运行,则省略
RunLoop.main.run()
意味着您的程序也会立即结束,并且合成器永远没有机会说话。

要了解语音事件(例如,当合成器开始和停止说话时),您需要创建一个符合

AVSpeechSynthesizerDelegate
协议的类型,并将该类型的实例设置为合成器的委托。然后您可以根据需要响应事件。


顺便说一句,

DispatchSemaphore
一般不建议用于此类同步目的,因为作为极低级的同步工具,它可能会导致优先级反转(如果使用不当,很容易死锁)。如果您详细说明尝试使用信号量的原因,我们可以就如何最好地替换它提供更有针对性的建议。

© www.soinside.com 2019 - 2024. All rights reserved.