2014-08-29 14 views
15

Wie kann ich interagieren mit Funktionen in Swift, die Größe C-Arrays zu nehmen?UnsafeMutablePointer in swift als Ersatz für C-Array der richtigen Größe in Obj-C

Ich lese durch Interacting with C APIS und kann immer noch nicht herausfinden.

Die Dokumentation für den Parameter coords von func getCoordinates(_ coords:UnsafeMutablePointer<CLLocationCoordinate2D>,range range: NSRange) besagt: "Bei der Eingabe müssen Sie ein C-Array mit Strukturen bereitstellen, die groß genug sind, um die gewünschte Anzahl an Koordinaten zu enthalten. Bei Ausgabe enthält diese Struktur die angeforderten Koordinatendaten."

Ich habe versucht, einige Dinge, die zuletzt:

var coordinates = UnsafeMutablePointer<CLLocationCoordinate2D>(calloc(1, UInt(polyline.pointCount))) 

Ziehen meine Haare hier ... irgendwelche Gedanken:

var coordinates: UnsafeMutablePointer<CLLocationCoordinate2D> = nil 
polyline.getCoordinates(&coordinates, range: NSMakeRange(0, polyline.pointCount)) 

Würde ich so etwas wie verwenden?

+0

Haben Sie versucht: 'var coordinates = UnsafeMutablePointer ()'? –

+0

Leider ja. Ergebnisse in: ''UnsafeMutablePointer ' ist nicht identisch mit 'CLLocationCoordinate2D'' was für mich eigentlich keinen Sinn ergibt, da es auch' UnsafeMutablePointer ' in der Funktion sein sollte. –

+0

Ich bekomme keinen Compilerfehler mit 'var coordinates = [CLLocationCoordinate2D]()', aber die 'getCoordinates' Funktion gibt nichts an' & coordinates' zurück. –

Antwort

46

Normalerweise kann man nur ein Array von der erforderlichen Art als in-out-Parameter übergeben, auch bekannt als

var coords: [CLLocationCoordinate2D] = [] 
polyline.getCoordinates(&coords, range: NSMakeRange(0, polyline.pointCount)) 

aber Dokumentation macht es wie eine schlechte Idee scheinen! Glücklicherweise bietet UnsafeMutablePointer eine statische alloc(num: Int) Methode, so dass Sie getCoordinates() wie folgt aufrufen können:

var coords: [CLLocationCoordinate2D] = [] 
for i in 0..<polyline.pointCount { 
    coords.append(coordsPointer[i]) 
} 
:

var coordsPointer = UnsafeMutablePointer<CLLocationCoordinate2D>.alloc(polyline.pointCount) 
polyline.getCoordinates(coordsPointer, range: NSMakeRange(0, polyline.pointCount)) 

Um die tatsächlichen CLLocationCoordinate2D Objekte aus dem wandelbaren Zeiger zu erhalten, sollten Sie durch nur Schleife in der Lage sein,

Und da Sie nicht über einen Speicherverlust wollen, schließen Sie wie folgt:

coordsPointer.dealloc(polyline.pointCount) 

erinnerte nur Array eine reserveCapacity() Instanz-Methode hat, so eine viel einfachere (und wahrscheinlich sicherer) Version davon wäre:

var coords: [CLLocationCoordinate2D] = [] 
coords.reserveCapacity(polyline.pointCount) 
polyline.getCoordinates(&coords, range: NSMakeRange(0, polyline.pointCount)) 
+10

Wer bist du und warum sind wir nicht die besten Freunde? –

+13

Hey, ich bin hier und alles, aber du rufst nie an. –

+1

Ich habe noch eine Frage: WARUM würde die API "UnsafeMutablePointer" statt eines guten alten optimierten Swift-Arrays verwenden? Scheint so viel zusätzlicher Aufwand für nichts. –

0

Erweiterung Wrapper für umfangreiche Antwort des @Nate Koch, kann nicht die reserveCapacity() Version zu arbeiten , es bleibt leeres Objekt zurück.