CoreAudioの中の、AudioToolboxに取り組んでいます。

システムサウンド自体は1行で鳴らせます。※マナーモードは解除

 AudioServicesPlaySystemSound(1108) // シャッター音

鳴らし終えたときに呼ばれるコールバック関数を

AudioServicesAddSystemSoundCompletiondeで登録しようとして、

つまづきましたショボーン

 

C言語のように、関数名がその関数へのポインタを表すのは Swiftも同じですが、

ここにはグローバル関数を指定しなければいけませんでした。

private func myCompletionCallback(ssID: SystemSoundID, clientData: UnsafeMutableRawPointer?) {
    print("didPlay")
}
class ViewController: UIViewController {
    ︙
        AudioServicesAddSystemSoundCompletion(ssID, nil, nil, myCompletionCallback, nil)
        AudioServicesPlaySystemSound(ssID)

AudioToolboxはC言語で実装された非同期の処理で、メンバー関数だと

鳴り終えた時のコールバック先が有効だという保証がない、という事ですかね。

Swiftの中だけならARCが効くので、メンバー関数を渡すこともできます。

 

これに気付くのに1日かかりました滝汗

「Swiftではポインタの書き方が違うのかも」と勘違いしてしまったからです。

 

 

ちなみにクロージャだとこうです。

    AudioServicesAddSystemSoundCompletion(ssID, nil, nil, myCompletionCallback, nil)
        AudioServicesPlaySystemSound(ssID)
  }
  let myCompletionCallback: @convention(c) (SystemSoundID, UnsafeMutableRawPointer?) -> Void
   = {(ssID, clientData) in
    print("didPlay")
  }

クロージャは、渡してしまえばあとはお好きにどうぞという事でしょうか。

AudioServicesAddSystemSoundCompletionの定義には、

@escapingというディレクティブが付いています。

 

 

 

 

しかし、とんだ回り道をしたおかげで、

Swiftのポインタについて調べるきっかけとなりました。

…とでも思わなければやっていられませんもぐもぐ

 

Swiftでは、C言語のポインタ関係のテクニックに、いちいち名前が付いています。

例えば 「void *」は、UnsafeMutableRawPointerというそうですびっくり

プロレスの大技みたいですね炎筋肉

上の例だとさらに、Optional UnsafeMutableRawPointerですか。

 

疲れます汗