2017-03-01 15 views
3

私は現在、Chris Adamsonの「Learning Core Audio」を読んでおり、Swift 3Objective-Cの代わりに)に沿ってフォローしようとしています。Swift 3 - UnsafePointer <CFDictionary>を使用していますか?

最初のコード例では、AudioToolを使用して、オーディオファイルに関する情報を収集しています。マイスウィフト3バージョンは、次のようになります

import Foundation 
import AudioToolbox 

func main() { 
    let arguments = CommandLine.arguments 

    guard arguments.count > 1 else { 
     print("Usage: CAMetaData /full/path/to/audiofile") 
     return 
    } 

    // Get filepath out of cmd-arguments 
    let audiofilePath = NSString(string: arguments[1]).expandingTildeInPath 

    // Load audio file into appropriate data structure 
    let audioURL = NSURL(fileURLWithPath: audiofilePath) 
    var audiofile: AudioFileID? = nil 
    var possibleError = noErr 

    possibleError = AudioFileOpenURL(audioURL, AudioFilePermissions.readPermission, 0, &audiofile) 
    assert(possibleError == noErr) 

    // Get size of metadata dictionary 
    var outDataSize: UInt32 = 0 

    possibleError = AudioFileGetPropertyInfo(audiofile!, kAudioFilePropertyInfoDictionary, &outDataSize, nil) 
    assert(possibleError == noErr) 

    // Get metadata 
    var outDataPointer: UnsafePointer<CFDictionary>? = nil 

    possibleError = AudioFileGetProperty(audiofile!, kAudioFilePropertyInfoDictionary, &outDataSize, &outDataPointer) 
    assert(possibleError == noErr) 

    // How to use this outDataPointer? 
    let outData = outDataPointer!.pointee as NSDictionary 
    dump(outData) 

    // No CFRelease necessary - Swift takes care of that 

    // Close connection to audiofile 
    possibleError = AudioFileClose(audiofile!) 
    assert(possibleError == noErr) 
} 

main() 

すべてが素晴らしい(すべての表明/ AudioToolbox -APIコールパスを)動作するようです。今私はoutDataPointerの中に格納されているデータをどのように表示できるか自分に尋ねています。

これは私が状況を理解する方法です。outDataPointerには、オプションの関連タイプUnsafePointer<CFDictionary>が保持されています。 outDataPointernilではないことを確認できます。したがって、関連付けられた値にアクセスしてもプログラムがクラッシュすることはありません。 outDataPointer!.pointeeCFDictionaryに、outDataPointerの背後にある関連する値で示されているはずです。 CFDictionaryNSDictionaryにキャスト可能です。

は悲しいコンソールへ

  • __NSAtom#0

下地データの印刷をダンプ。まさに私が期待したものではない(オーディオファイルに関する情報)。このデータを私のoutDataPointer変数からどのように得ることができますか?

答えて

5

スウィフトのCFDictionary自体がデータ構造ではありません。これはデータ構造体へのポインタであり、Objective-CのCFDictionaryRefに相当します。つまり、スウィフトclassのように動作し、structではなく動作します。

outDataPointerに書き込まれた値は、CFDictionaryへのポインタではありません。 a CFDictionaryです。あまりにも何度も参照を外しているので、辞書に格納されたデータが辞書へのポインタとして扱われます。私のシステムでは、結果のメモリアドレスは0x001dffffc892e2f1であり、Objective-Cはtagged pointerとして扱い、NSAtomというメッセージになりました。 UnsafePointer<CFDictionary>?の代わりにCFDictionary?としてoutDataPointerを宣言し、問題を解決するには

// Get metadata 
var outDataPointer: CFDictionary? = nil 

possibleError = AudioFileGetProperty(audiofile!, kAudioFilePropertyInfoDictionary, &outDataSize, &outDataPointer) 
assert(possibleError == noErr) 

let outData = outDataPointer! as NSDictionary 
dump(outData) 

出力:

▿ 1 key/value pair #0 
    ▿ (2 elements) 
    - .0: approximate duration in seconds #1 
     - super: __NSCFString 
     - super: NSMutableString 
      - super: NSString 
      - super: NSObject 
    - .1: 187.387 #2 
     - super: NSString 
     - super: NSObject 
+0

は、詳細な回答ありがとうございます!これは間違いなく私のために物事をクリアしました。私は、最初に 'UnsafePointer 'を使ってどうやって終わったのかは分かりません。すべてが今期待どおりに動作しています。 – Herickson

+0

@NobodyNada、 'AudioFileGetProperty'で' NSDictionary'を使用できるのであれば、 'CFDictionary'を使う理由は何ですか? Swift Dictionaryを使用する方法はありますか? (私は[String:Any]を試しましたが、キー/値で埋められませんでした...)ありがとう –

関連する問題