Swift UnsafeMutablePointer?> allocation and print

前端 未结 1 1165
醉话见心
醉话见心 2020-12-09 22:07

I\'m new to swift and I have some difficulties to deal with pointers of unmanaged CFString (or NSString). I\'m working on a CoreMIDI project that implies usage of UnsafeMuta

相关标签:
1条回答
  • 2020-12-09 22:39

    I have no experience with CoreMIDI and could not test it, but this is how it should work:

    let midiEndPoint = MIDIGetSource(0)
    var property : Unmanaged<CFString>?
    let err = MIDIObjectGetStringProperty(midiEndPoint, kMIDIPropertyDisplayName, &property)
    if err == noErr {
        let displayName = property!.takeRetainedValue() as String
        println(displayName)
    }
    

    As @rintaro correctly noticed, takeRetainedValue() is the right choice here because it is the callers responsibility to release the string. This is different from the usual Core Foundation memory management rules, but documented in the MIDI Services Reference:

    NOTE

    When passing a Core Foundation object to a MIDI function, the MIDI function will never consume a reference to the object. The caller always retains a reference which it is responsible for releasing by calling the CFRelease function.

    When receiving a Core Foundation object as a return value from a MIDI function, the caller always receives a new reference to the object, and is responsible for releasing it.

    See "Unmanaged Objects" in "Working with Cocoa Data Types" for more information.

    UPDATE: The above code works only when compiling in 64-bit mode. In 32-bit mode, MIDIObjectRef and MIDIEndpointRef are defined as different kind of pointers. This is no problem in (Objective-)C, but Swift does not allow a direct conversion, an "unsafe cast" is necessary here:

    let numSrcs = MIDIGetNumberOfSources()
    println("number of MIDI sources: \(numSrcs)")
    for srcIndex in 0 ..< numSrcs {
        #if arch(arm64) || arch(x86_64)
        let midiEndPoint = MIDIGetSource(srcIndex)
        #else
        let midiEndPoint = unsafeBitCast(MIDIGetSource(srcIndex), MIDIObjectRef.self)
        #endif
        var property : Unmanaged<CFString>?
        let err = MIDIObjectGetStringProperty(midiEndPoint, kMIDIPropertyDisplayName, &property)
        if err == noErr {
            let displayName = property!.takeRetainedValue() as String
            println("\(srcIndex): \(displayName)")
        } else {
            println("\(srcIndex): error \(err)")
        }
    }
    
    0 讨论(0)
提交回复
热议问题