Ios Swift非女性化指针<;非托管<;CFString>&燃气轮机;分配和打印
我是swift新手,在处理非托管CFString(或NSString)的指针时遇到一些困难。 我正在从事一个CoreMIDI项目,该项目意味着使用UnsafeMutablePointer?>正如您在该函数中看到的: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
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)")
}
}