我目前正在阅读Chris的“学习核心音频”(Learning),并尝试在Swift 3 (而不是Objective)中继续学习。
第一个代码示例使用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调用pass)。现在,我在问自己如何能够显示存储在outDataPointer中的数据。
我就是这样理解这种情况的:outDataPointer持有一个带有关联类型UnsafePointer<CFDictionary>的可选选项。我能够验证outDataPointer不是nil,因此访问相关的值不会使我的程序崩溃。outDataPointer!.pointee应该给出outDataPointer背后的关联值所指向的CFDictionary。CFDictionary对NSDictionary来说是可移植的。
可悲的是丢弃了底层的数据打印
到控制台去。与我所期望的完全不同(关于音频的信息)。如何从我的outDataPointer变量中获取这些数据?
发布于 2017-03-02 00:15:42
Swift的CFDictionary本身并不是一个数据结构;它是一个指向数据结构的指针,它相当于Objective的CFDictionaryRef。换句话说,它的行为像一个Swift class,而不是一个struct。
写入outDataPointer的值不是指向CFDictionary的指针,而是CFDictionary。取消引用次数过多,导致存储在字典中的数据被视为指向字典的指针。在我的系统中,产生的内存地址是0x001dffffc892e2f1,目标-C将其视为标记指针,从而产生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: NSObjecthttps://stackoverflow.com/questions/42544160
复制相似问题