Swift 3 - 使用 UnsafePointer<CFDictionary>?
Swift 3 - Working with UnsafePointer<CFDictionary>?
我目前正在阅读 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
应该给我 outDataPointer
后面的关联值指向的 CFDictionary
。 CFDictionary
可转换为 NSDictionary
。
可悲地丢弃底层数据打印
- __NSAtom #0
到控制台。完全不是我所期望的(关于音频文件的信息)。如何从我的 outDataPointer
变量中获取这些数据?
Swift 的 CFDictionary
本身不是数据结构;它是一个指向数据结构的指针,相当于Objective-C的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
我目前正在阅读 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
应该给我 outDataPointer
后面的关联值指向的 CFDictionary
。 CFDictionary
可转换为 NSDictionary
。
可悲地丢弃底层数据打印
- __NSAtom #0
到控制台。完全不是我所期望的(关于音频文件的信息)。如何从我的 outDataPointer
变量中获取这些数据?
Swift 的 CFDictionary
本身不是数据结构;它是一个指向数据结构的指针,相当于Objective-C的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