Swift 3 - 使用 UnsafePointer<CFDictionary>?
Posted
技术标签:
【中文标题】Swift 3 - 使用 UnsafePointer<CFDictionary>?【英文标题】:Swift 3 - Working with UnsafePointer<CFDictionary>? 【发布时间】:2017-03-01 23:32:28 【问题描述】:我目前正在阅读 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
到控制台。完全不是我所期望的(有关音频文件的信息)。如何从我的 outDataPointer
变量中获取这些数据?
【问题讨论】:
【参考方案1】: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
【讨论】:
感谢您的详细解答!这无疑为我解决了问题。我什至不确定我最初是如何使用UnsafePointer<CFDictionary>
的。现在一切正常。
@NobodyNada,如果我们可以在AudioFileGetProperty
中使用NSDictionary
,那么使用CFDictionary
的原因是什么?有没有办法使用 Swift Dictionary? (我试过 [String:Any] 并没有填充键/值...)谢谢以上是关于Swift 3 - 使用 UnsafePointer<CFDictionary>?的主要内容,如果未能解决你的问题,请参考以下文章
“当前 SwiftyJSON(通过 Swift 3.0.2)无法使用 Swift 3.1 导入”的原因是啥
使用 Swift 2.3 编译的模块无法在 Swift 3.0 中导入
使用 Swift 3.0.1 编译的模块无法在 BuddyBuild 上的 Swift 3.0 中导入
Cocoapods - 使用 Swift 3.0 编译的模块无法在 Swift 3.0.1 中导入