2017-03-01 66 views
3

我正在閱讀Chris Adamson的「Learning Core Audio」,並嘗試沿着Swift 3(而不是Objective-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>的可選項。我可以驗證outDataPointer不是nil,因此訪問關聯的值不會使我的程序崩潰。 outDataPointer!.pointee應該給我由outDataPointer後面的相關值指向。 CFDictionary澆注到NSDictionary

可悲傾倒墊層數據打印

  • __NSAtom#0

到控制檯。不是我所期望的(有關audiofile的信息)。如何從我的outDataPointer變量中獲取這些數據?

回答

5

斯威夫特的CFDictionary本身並不是一個數據結構;它是一個指向數據結構的指針,它等價於Objective-C的CFDictionaryRef。換句話說,它表現得像Swift class,而不是struct

寫入outDataPointer的值不是指向CFDictionary的指針;它 a CFDictionary。您多次解除引用它,導致存儲在字典中的數據被視爲指向字典的指針。在我的系統上,得到的內存地址是0x001dffffc892e2f1,Objective-C將其視爲tagged pointer,導致產生NSAtom消息。

要解決此問題,聲明outDataPointer作爲的CFDictionary?而不是UnsafePointer<CFDictionary>?

// 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? (我試過[字符串:任何],它沒有填充鍵/值...)謝謝 –

相關問題