简体   繁体   English

Swift 3 - 使用UnsafePointer <CFDictionary>?

[英]Swift 3 - Working with UnsafePointer<CFDictionary>?

I'm currently reading Chris Adamson's "Learning Core Audio" and try to follow along in Swift 3 (instead of Objective-C ). 我目前正在阅读Chris Adamson的“学习核心音频”并尝试在Swift 3 (而不是Objective-C )中继续学习。

The first code example makes use of AudioTool to gather information about an audio-file. 第一个代码示例使用AudioTool来收集有关音频文件的信息。 My Swift 3 version looks like this: 我的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()

Everything seems to work great (all assertions/ AudioToolbox -API call pass). 一切似乎都很好(所有断言/ AudioToolbox调用传递)。 Now I'm asking myself how I'm able to display the data stored inside the outDataPointer . 现在我问自己如何能够显示存储在outDataPointer的数据。

This is how I understand the situation: outDataPointer holds an optional with associated type UnsafePointer<CFDictionary> . 这就是我理解这种情况的方法: outDataPointer包含一个带有关联类型UnsafePointer<CFDictionary> I'm able to verify that outDataPointer is not nil , therefore accessing the associated value won't crash my program. 我能够验证outDataPointer不是nil ,因此访问相关值不会导致我的程序崩溃。 outDataPointer!.pointee should give me the CFDictionary pointed to by the associated value behind outDataPointer . outDataPointer!.pointee应该给我一个由outDataPointer背后的关联值指向的CFDictionary CFDictionary is castable to NSDictionary . CFDictionary可以转换为NSDictionary

Sadly dumping the underlaying data prints 遗憾的是,倾销了下层数据

  • __NSAtom #0 __NSAtom#0

to the console. 到控制台。 Quite not what I expected (information about the audiofile). 不是我所期望的(关于audiofile的信息)。 How can I get this data out of my outDataPointer variable? 如何从outDataPointer变量中获取此数据?

Swift's CFDictionary isn't itself a data structure; Swift的CFDictionary本身不是一个数据结构; it's a pointer to a data structure, and it is equivalent to Objective-C's CFDictionaryRef . 它是指向数据结构的指针,它等同于Objective-C的CFDictionaryRef In other words, it behaves like a Swift class , not a struct . 换句话说,它的行为类似于Swift class ,而不是struct

The value written into outDataPointer is not a pointer to a CFDictionary ; 写入outDataPointer的值不是指向CFDictionary的指针; it is a CFDictionary . 一个CFDictionary You're dereferencing it one too many times, causing the data stored in the dictionary to be treated as a pointer to a dictionary. 您将其解除引用次数太多次,导致存储在字典中的数据被视为指向字典的指针。 On my system, the resulting memory address was 0x001dffffc892e2f1 , which Objective-C treats as a tagged pointer , resulting in the NSAtom message. 在我的系统上,生成的内存地址为0x001dffffc892e2f1 ,Objective-C将其视为标记指针 ,从而生成NSAtom消息。

To fix the problem, declare outDataPointer as a CFDictionary? 要解决此问题, outDataPointer声明为CFDictionary? instead of an UnsafePointer<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)

Output: 输出:

▿ 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM