为什么 NSSpeechSynthesizer 不调用它的委托方法?

Why is NSSpeechSynthesizer not calling its delegate methods?

当我在 NSSpeechSynthesizer 实例上调用 startSpeaking(String) 方法时,设置了委托,会说话,但以下委托方法永远不会触发:

speechSynthesizer(_ sender: NSSpeechSynthesizer, 
              willSpeakWord characterRange: NSRange, 
                         of string: String)

func speechSynthesizer(_ sender: NSSpeechSynthesizer, 
          didFinishSpeaking finishedSpeaking: Bool)

为什么?我正在使用 Swift 4; XCode9.1; MacOS 10.13.1

重现步骤:

编译并运行以下内容:

import AppKit

class SynthDelegate: NSObject, NSSpeechSynthesizerDelegate {

    var str = ""

    func speechSynthesizer(_ sender: NSSpeechSynthesizer, willSpeakWord characterRange: NSRange, of string: String) {
        str = "spoke a word"
    }

    func speechSynthesizer(_ sender: NSSpeechSynthesizer, didFinishSpeaking finishedSpeaking: Bool) {
        str = "finished speaking"
    }

}

let mySpeaker = NSSpeechSynthesizer()

let myDelegate = SynthDelegate()

mySpeaker.delegate = myDelegate

mySpeaker.startSpeaking("test string to read aloud")

sleep(5) // keep alive while speaking

print(myDelegate.str)

预期结果:

"finished speaking"

实际结果:

""

更新

基于 OOPers 出色的答案,以下在新测试项目中有效:

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {



    func applicationDidFinishLaunching(_ aNotification: Notification) {
        // Insert code here to initialize your application

        let mySpeaker = NSSpeechSynthesizer()
        let myDelegate = SynthDelegate()
        mySpeaker.delegate = myDelegate
        mySpeaker.startSpeaking("test string to read aloud")


        Timer.scheduledTimer(withTimeInterval: 5.0, repeats: false) {_ in
            print(myDelegate.str)

        }
    }

    func applicationWillTerminate(_ aNotification: Notification) {
        // Insert code here to tear down your application
    }


}


class SynthDelegate: NSObject, NSSpeechSynthesizerDelegate {
    var str = ""

    func speechSynthesizer(_ sender: NSSpeechSynthesizer, willSpeakWord characterRange: NSRange, of string: String) {
        str = "spoke a word"
        print(str)
    }

    func speechSynthesizer(_ sender: NSSpeechSynthesizer, didFinishSpeaking finishedSpeaking: Bool) {
        str = "finished speaking"
        print(str)
    }
}

您是否在 Playground 中测试您的代码?无论如何,你永远不应该在你的应用程序中调用 sleep(),包括 Playground 代码。

它阻止了使框架正常工作所需的许多活动,例如调用委托方法。当你需要延迟执行一些代码时,你可以使用 Timer

可在 Playground 中测试:

import AppKit

class SynthDelegate: NSObject, NSSpeechSynthesizerDelegate {
    var str = ""

    func speechSynthesizer(_ sender: NSSpeechSynthesizer, willSpeakWord characterRange: NSRange, of string: String) {
        str = "spoke a word"
        print(str)
    }

    func speechSynthesizer(_ sender: NSSpeechSynthesizer, didFinishSpeaking finishedSpeaking: Bool) {
        str = "finished speaking"
        print(str)
    }
}

let mySpeaker = NSSpeechSynthesizer()
let myDelegate = SynthDelegate()
mySpeaker.delegate = myDelegate
mySpeaker.startSpeaking("test string to read aloud")

import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true

Timer.scheduledTimer(withTimeInterval: 5.0, repeats: false) {_ in
    print(myDelegate.str)
    PlaygroundPage.current.finishExecution()
}