質問: Timer.scheduledTimer(timeInterval:0.5,target:self,selector:#selector(self.enterFrame),userInfo:nil,repeats:true) timer.fire() } override func viewDidDisappear(_ animated: Bool) { super.viewDidDisappear(true) //タイマー破棄? timer.invalidate() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } ```
回答: iPadやSwiftに暗いのですが一般的な問題と捉えた範囲でのコメントをします。 音声の再生が始まるとハードウェアによるバックグラウンド処理により発音されるのですが、ハードウェアを動かすための初期動作に多少時間がかかることはよくあると思います。例えばバッファを確保してそこへ全部あるいは一部の音声データを読み込んだりといったことが考えられます。あらかじめ音量0で鳴らすと現象が軽減されるというのは、初期動作で行ったI/O結果がキャッシュされたためと考えられます。 いずれにせよ音を鳴らすための処理に数10msec~100msecオーダーの時間がかかるとしてそれをUIスレッドで直接行ってしまうとご質問のような影響が出る結果になると思います。 対応としては一般的に以下のような考え方にすると思います。 * バックグラウンド処理を行うためのスレッドをあらかじめ起動しておく 例えばマウスドラッグで音を鳴らすような画面を開いた時点でスレッドを起動してしまいます。音を鳴らす処理はこのスレッド上で行うようにします。 * UIスレッドではバックグラウンドスレッドへ簡単な指示(この音を鳴らせなど)のみ行う どんな言語・ライブラリーでもスレッド間の同期をとるための機能が提供されていると思いますのでそうしたものを使いスレッド間で情報のやりとりを行います。ただ今回のようなものですと厳密なスレッド間同期の必要性は低く、単にUIスレッドから鳴らしたい音が変化した際に大域変数的なものへ音の種類を直接設定し、バックグラウンドスレッドでは100msec前後の間隔でその変数を監視しつつ音を鳴らすといったシンプルな作りでもよい気もします。