2017-11-27 1 views
-2

質問は本当に簡単です。 私は保持サイクルを検出することを知っていますが、次の例ではサイクルを保持しているかどうかを知りたいと思います。スイフト - 自生していないサイクルを保持していますか?

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

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

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

      }) 
     }) 
    }) 

MainManager強いREFにplayerクラスを維持sound強いREFにsoundを保つシングルトンクラスである、と。

話すの実装()

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

私はちょうどあなたが見てplsを取ることができる質問を編集する? –

答えて

1

答えは "それが依存" です。

MainManagersoundsoundへの強い参照を持っている場合playerplayer.speak()への強い参照がplayerは[はい、あなたは強い基準周期を持って、それは取り除くことができないことを閉鎖への強い参照を保持しますました。

、しかし、speakだけの非同期キューに閉鎖を置き、再びそれを参照することはありません場合は、OKになります。

+0

ありがとう、私はちょうどあなたが見てplsを取ることができる質問を編集する? –

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

はよく見える、それについて考えることはありません:) –

関連する問題