Ich bin neu zu schnell und ich habe einige Schwierigkeiten, mit Zeigern von nicht verwalteten CFString (oder NSString) umzugehen. Ich arbeite an einem Projekt, die Coremidi Nutzung von UnsafeMutablePointer impliziert>, wie Sie in dieser Funktion sehen:Swift UnsafeMutablePointer <Unmanaged ?> Zuordnung und Drucken
func MIDIObjectGetStringProperty(_ obj: MIDIObjectRef,
_ propertyID: CFString!,
_ str: UnsafeMutablePointer<Unmanaged<CFString>?>) -> OSStatus
Mein Problem ist, dass ich einen Puffer zu erhalten, den Inhalt der Eigenschaft zugewiesen werden soll (_str) Rufen Sie dann die obige Funktion auf und drucken Sie den Inhalt schließlich mit println in der Konsole aus.
Im Moment habe ich dies:
// 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)
ich nicht im Internet keinen Beispielcode finden, um Coremidi-Funktionen auf Apfel developper Bibliothek zu verwenden. Ich bin wirklich verwirrt, weil ich von cpp komme und die Dinge sind sehr unterschiedlich in swift.
EDIT:
Nach Rintaro und Martin Antworten, die ich habe immer noch ein Problem, alle meine Tests sind auf iOS getan 8.1 und wenn ich kopieren Sie den Code, den Sie zu mir gebracht der Compiler sagt mir, dass ich nicht schreiben kann:
let err = MIDIObjectGetStringProperty(midiEndPoint, kMIDIPropertyDisplayName, &property)
Ergebnisse in "Unmanaged" ist nicht in "MIDIObjectRef" konvertierbar. Also habe ich eine "&" hinzugefügt, weil MIDIObjectRef ist ein unsafeMutablePointer <void>.
let midiEndPoint = MIDIGetSource(0)
var property : Unmanaged<CFString>?
let err = MIDIObjectGetStringProperty(&midiEndPoint, kMIDIPropertyDisplayName, &property)
Jetzt: 'Unmanaged <MIDIEndpoint>' ist nicht konvertierbar '@lvalue inout $ T2'. Schließlich musste ich das erste mal auf var umstellen, ohne zu verstehen warum?!?
var midiEndPoint = MIDIGetSource(0)
var property : Unmanaged<CFString>?
let err = MIDIObjectGetStringProperty(&midiEndPoint, kMIDIPropertyDisplayName, &property)
Der Code kompiliert jetzt und läuft, aber MIDIObjectGetStringProperty gibt OSStatus -50 irren, die IOW oder von MacErros.h entspricht:
paramErr = -50, /*error in user parameter list*/
So scheint es, dass die Parameter sind nicht diejenigen, die MIDIObjectGetStringProperty ist warten auf.
Die Quelle "0" nicht auf meinem iPad existieren, weil MIDIGetNumberOfSources() gibt 1. Hier ist der vollständige Code:
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))
}
}
Displays:
MIDI Destinations : 1
error : -50
ich etwas verstehe wirklich nicht. ..
UPDATE:
Schließlich fand Martin die Lösung, Es scheint, dass es zwei unterschiedliche Definitionen von MIDIObjectRef in 32- und 64-Bit-Architekturen gibt. Als ich den Code auf einem alten iPad 2 ausführte, versuchte mein Code, im 32bits Modus zu kompilieren, in dem MIDIGetSource (i) Rückgabewert nicht in MIDIObjectRef umwandelbar ist. Die Lösung ist „unsicher cast“ der MIDI-Endpunkt auf 32-Bit-Architekturen:
#if arch(arm64) || arch(x86_64)
let midiEndPoint = MIDIGetDestination(i)
#else
let midiEndPoint = unsafeBitCast(MIDIGetDestination(i), MIDIObjectRef.self)
#endif
... Oder ein neues 64-Bit-Geräte zu kaufen ...
Vielen Dank für die wertvolle Hilfe
Ich bestätigte dies funktioniert, aber ich denke, wir 'takeRetainedValue verwenden sollten() ', denn in diesem Fall haben wir die Verantwortung, den zurückgegebenen' CFString' freizugeben. – rintaro
@rintaro: "MIDIObjectGetStringProperty" hat in seinem Namen nicht "Create" oder "Copy". Gemäß den Speicherverwaltungsregeln von Core Foundation ist der Aufrufer nicht für die Freigabe des Speichers verantwortlich. Siehe https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html. Ich denke, dass die "Get Rule" hier gilt. –
Aber tatsächlich habe ich bestätigt, dass es Lecks gibt. siehe: https://developer.apple.com/library/mac/qa/qa1374/_index.html – rintaro