Ios Swift非女性化指针<;非托管<;CFString>&燃气轮机;分配和打印

Ios Swift非女性化指针<;非托管<;CFString>&燃气轮机;分配和打印,ios,swift,unmanaged,midi,unsafe-pointers,Ios,Swift,Unmanaged,Midi,Unsafe Pointers,我是swift新手,在处理非托管CFString(或NSString)的指针时遇到一些困难。 我正在从事一个CoreMIDI项目,该项目意味着使用UnsafeMutablePointer?>正如您在该函数中看到的: func MIDIObjectGetStringProperty(_ obj: MIDIObjectRef, _ propertyID: CFString!, _ str: U

我是swift新手,在处理非托管CFString(或NSString)的指针时遇到一些困难。 我正在从事一个CoreMIDI项目,该项目意味着使用UnsafeMutablePointer?>正如您在该函数中看到的:

func MIDIObjectGetStringProperty(_ obj: MIDIObjectRef,
                           _ propertyID: CFString!,
                           _ str: UnsafeMutablePointer<Unmanaged<CFString>?>) -> OSStatus
“非托管”中的结果不能转换为“MIDIObjectRef”。 所以我添加了一个“&”,因为MIDIObjectRef是一个不可配置的指针

因此,这些参数似乎不是MIDIObjectGetStringProperty正在等待的参数

源“0”确实存在于我的iPad上,因为MIDIGetNumberOfSources()返回1。以下是完整的代码:

var numDestinations: ItemCount = MIDIGetNumberOfDestinations()
    println("MIDI Destinations : " + String(numDestinations))

    for var i : ItemCount = 0 ; i < numDestinations; ++i{
        var midiEndPoint = MIDIGetDestination(i)

        var property : Unmanaged<CFString>?
        let err = MIDIObjectGetStringProperty(&midiEndPoint, kMIDIPropertyDisplayName, &property)
        if err == noErr {
            let displayName = property!.takeRetainedValue() as String
            println(displayName)
        }else{
            println("error : "+String(err))
        }
   }
我真的什么都不懂

更新:

最后Martin找到了解决方案,似乎在32位和64位体系结构中有两种不同的MIDIObjectRef定义。当我在旧的iPad2上运行代码时,我的代码试图在32位模式下编译,其中MIDIGetSource(I)返回值不能转换为MIDIObjectRef。解决方案是在32位体系结构上“不安全地强制转换”midi端点:

#if arch(arm64) || arch(x86_64)
    let midiEndPoint = MIDIGetDestination(i)
#else
    let midiEndPoint = unsafeBitCast(MIDIGetDestination(i), MIDIObjectRef.self)
#endif
。。。或者购买新的64位设备


感谢您的宝贵帮助

我没有CoreMIDI的经验,也无法测试它,但它应该是这样工作的:

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)
}

我确认了这一点,但我认为我们应该使用
takeRetainedValue()
,因为在这种情况下,我们有责任释放返回的
CFString
@rintaro:“MIDIObjectGetStringProperty”的名称中没有“Create”或“Copy”。根据核心基础内存管理规则,这意味着调用方不负责释放内存。看见我认为“获取规则”适用于这里。但事实上,我证实了它是泄漏的。请看:很抱歉有点不在场,但我不知道是否有人看到了我的其他消息,我仍然有问题使代码工作。我也不知道在stackoverflow上添加评论或新的“答案”之间的最佳实践是什么。谢谢lot@Martin成功了!这太疯狂了,我现在不明白为什么。这是平常的事吗?它是否来自其他版本的iOS SDK?无论如何,我可以告诉你一个大大的“谢谢”,因为我自己肯定不会找到这个。
var midiEndPoint = MIDIGetSource(0)
var property : Unmanaged<CFString>?
let err = MIDIObjectGetStringProperty(&midiEndPoint, kMIDIPropertyDisplayName, &property)
paramErr  = -50,  /*error in user parameter list*/
var numDestinations: ItemCount = MIDIGetNumberOfDestinations()
    println("MIDI Destinations : " + String(numDestinations))

    for var i : ItemCount = 0 ; i < numDestinations; ++i{
        var midiEndPoint = MIDIGetDestination(i)

        var property : Unmanaged<CFString>?
        let err = MIDIObjectGetStringProperty(&midiEndPoint, kMIDIPropertyDisplayName, &property)
        if err == noErr {
            let displayName = property!.takeRetainedValue() as String
            println(displayName)
        }else{
            println("error : "+String(err))
        }
   }
MIDI Destinations : 1
error : -50
#if arch(arm64) || arch(x86_64)
    let midiEndPoint = MIDIGetDestination(i)
#else
    let midiEndPoint = unsafeBitCast(MIDIGetDestination(i), MIDIObjectRef.self)
#endif
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)
}
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)")
    }
}