2017-11-27 12 views
-2

질문은 정말 간단합니다. 나는주기를 알아내는 것을 알고 있지만 다음 예제에서 나는주기를 가지고 있는지 알고 싶다.스위프트 -주기가 유지되지 않습니까?

MainManager.sound.player.speak("1", didFinish: { 

     MainManager.sound.player.speak("3", didFinish: { 

      MainManager.sound.player.speak("4", didFinish: { 

      }) 
     }) 
    }) 

MainManager 강력한 심판에 sound을 유지 싱글 톤 클래스이며, sound 강한 심판에 player 클래스를 유지한다.

발언의 구현()

private var speechSynthesizer:AVSpeechSynthesizer? 
private var speechDidFinishCompletion:CompletionVoid? = nil 
func speak(_ stringToSpeak:String, didFinish:CompletionVoid? = nil) 
{ 
    if speechSynthesizer == nil 
    { 
     speechSynthesizer = AVSpeechSynthesizer() 
     speechSynthesizer?.delegate = self 
    } 

    speechDidFinishCompletion = didFinish 

    let speechUtterance = AVSpeechUtterance(string: stringToSpeak) 
    speechSynthesizer!.speak(speechUtterance) 
} 

func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) 
{ 
    speechDidFinishCompletion?() 
} 
+0

'speak' 메소드 구현을 게시 할 수 있습니까? –

+0

주기를 정확히 유지 하시겠습니까? 사물의 외모로 볼 때, 당신은 정적 인 멤버를 언급하는 것입니다. 더 많은 컨텍스트를 제공 할 수 있다면 가장 도움이 될 것입니다. – Hamish

+0

i'v는 질문을 편집 할 수 있습니까? –

답변

1

대답은 "이 달려있다"입니다. MainManagersound에 강한 참조를 가지고 soundplayer에 강한 참조를 가지고 player.speak()player 그것을 제거 할 수없는 폐쇄에 대한 강한 참조를 유지하게되면

, 다음 네, 당신은 강한 참조주기를 가지고있다.

그러나 speak은 비동기식 대기열에 클로저를 넣고 다시는 참조하지 않으면 OK입니다.

+0

감사합니다, i'v는 단지 질문을 편집 할 수 있습니까? –

0

완성 처리기를 호출 한 후에 참조를 이동하지 않으므로 유지주기가 발생할 수 있습니다. 클로저가 더 이상 sound의 인스턴스에 의해 참조되지 않는 한주기가 깨질 수 있습니다. 현재 "재귀 적"호출은 후속 호출에서 덮어 쓰기 때문에 처음 2 콜백이 해제되도록합니다. 마지막 코드가 덮어 쓰여지지 않기 때문에 마지막 클로저에주기가 남아 있으면이 코드가주기를 만듭니다.

다음과 같이 완성 처리기에 대한 참조를 안전하게 제거 할 수 있어야합니다.

func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) { 
    // Transfer ownership to the local scope in case the 
    // closure itself sets `speechDidFinishCompletion` 
    let localClosure = speechDidFinishCompletion 
    speechDidFinishCompletion = nil 

    localClosure?() 
} 
+0

좋아 보인다, 그것에 대해 생각하지 않았다 :) –