Я новичок в быстром, и у меня есть некоторые трудности с указателями неуправляемого CFString (или NSString). Я работаю над проектом CoreMIDI, который подразумевает использование UnsafeMutablePointer> как вы можете видеть в этой функции:?Swift UnsafeMutablePointer <Неуправляемый ?> Размещение и печать
func MIDIObjectGetStringProperty(_ obj: MIDIObjectRef,
_ propertyID: CFString!,
_ str: UnsafeMutablePointer<Unmanaged<CFString>?>) -> OSStatus
Моя проблема заключается в том, что я хочу, чтобы выделить буфер для получения содержания имущества (_str), затем вызовите функцию выше и, наконец, распечатайте содержимое в консоли с помощью println.
На данный момент я написал:
// Get the first midi source (I know it exists)
var midiEndPoint : Unmanaged<MIDIEndpointRef> = MIDIGetSource(0)
//C reate a "constant" of 256
let buf = NSMutableData(capacity: 256)
// Allocate a string buffer of 256 characters (I'm not even sure this does what I want)
var name = UnsafeMutablePointer<Unmanaged<CFString>?>(buf!.bytes)
// Call the function to fill the string buffer with the display name of the midi device
var err : OSStatus = MIDIObjectGetStringProperty(&midiEndPoint,kMIDIPropertyDisplayName,name)
// Print the string ... here no surprises I don't know what to write to print the content of the pointer, so it prints the address for the moment
println(name)
я не нашел пример кода для использования функции CoreMIDI на яблоне developper библиотеки не в Интернете. Я действительно смущен, потому что я родом из cpp, и все очень быстро меняется.
EDIT:
После Ринтары и Мартина ответы, которые я до сих пор есть проблемы, все мои испытания выполняются на прошивке 8.1 и если я скопировать код, который вы принесли мне компилятор говорит мне, что я не могу написать:
let err = MIDIObjectGetStringProperty(midiEndPoint, kMIDIPropertyDisplayName, &property)
Результаты в «Неуправляемом» не конвертируются в «MIDIObjectRef». Итак, я добавил «&», потому что MIDIObjectRef является UnsafeMutablePointer <void>.
let midiEndPoint = MIDIGetSource(0)
var property : Unmanaged<CFString>?
let err = MIDIObjectGetStringProperty(&midiEndPoint, kMIDIPropertyDisplayName, &property)
Теперь: 'Неуправляемый <MIDIEndpoint>' не конвертируются в '@lvalue Inout $ T2. Наконец, мне пришлось сменить первый вариант на var, не понимая почему?!?
var midiEndPoint = MIDIGetSource(0)
var property : Unmanaged<CFString>?
let err = MIDIObjectGetStringProperty(&midiEndPoint, kMIDIPropertyDisplayName, &property)
Теперь код компилируется и работает, но MIDIObjectGetStringProperty возвращает OSStatus заблуждаться -50, что соответствует IOW или MacErros.h:
paramErr = -50, /*error in user parameter list*/
Таким образом, кажется, что параметры не являются те, которые 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))
}
}
Дисплеи:
MIDI Destinations : 1
error : -50
я действительно ничего не понимаю. ..
UPDATE:
Наконец Мартин нашел решение, кажется, что существует два разных определения MIDIObjectRef в 32 и 64-битных архитектурах. Когда я запускаю код на старом iPad 2, мой код пытался скомпилировать в режиме 32 бит, где возвращаемое значение MIDIGetSource (i) не конвертируется в MIDIObjectRef. Решение состоит в том, чтобы «небезопасный слепок» миди конечной точки на 32 бит архитектуры:
#if arch(arm64) || arch(x86_64)
let midiEndPoint = MIDIGetDestination(i)
#else
let midiEndPoint = unsafeBitCast(MIDIGetDestination(i), MIDIObjectRef.self)
#endif
... Или купить новое устройство 64-битного ...
Спасибо за ценную помощь
Я подтвердил, что это работает, но я думаю, что мы должны использовать 'takeRetainedValue() ', потому что в этом случае мы несем ответственность за выпуск возвращенного' CFString'. – rintaro
@ rintaro: «MIDIObjectGetStringProperty» не имеет «Создать» или «Копировать» в его имени. Согласно правилам управления памятью Core Foundation, это означает, что вызывающий абонент не несет ответственности за освобождение памяти. См. Https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html. Я думаю, что здесь применяется «Get Rule». –
Но, фактически, я подтвердил, что он протекает. см. https://developer.apple.com/library/mac/qa/qa1374/_index.html – rintaro