我目前正在阅读Chris Adamson" Learning Core Audio"并尝试按照 Swift 3 (而不是 Objective-C )进行操作。
第一个代码示例使用AudioTool
来收集有关音频文件的信息。我的Swift 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
应该为CFDictionary
后面的相关值指出outDataPointer
。 CFDictionary
可投放到NSDictionary
。
遗憾地转储底层数据
- __ NSAtom#0
到控制台。不是我所期望的(关于audiofile的信息)。如何从outDataPointer
变量中获取此数据?
答案 0 :(得分:4)
CFDictionary
本身并不是一个数据结构;它是指向数据结构的指针,它等同于Objective-C&#39; s CFDictionaryRef
。换句话说,它的行为类似于Swift class
,而不是struct
。
写入outDataPointer
的值不是指向CFDictionary
的指针; 是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