2014-08-29 13 views
15

Come posso interagire con le funzioni in rapido utilizzate per acquisire array C di dimensioni?UnsafeMutablePointer in rapido come sostituto per C Array di dimensioni corrette in Obj-C

Ho letto tramite Interacting with C APIS e ancora non riesco a capirlo.

La documentazione per il parametro coords of func getCoordinates(_ coords:UnsafeMutablePointer<CLLocationCoordinate2D>,range range: NSRange) afferma: "All'ingresso, è necessario fornire un array C di strutture abbastanza grandi da contenere il numero di coordinate desiderato. In uscita, questa struttura contiene i dati di coordinate richiesti."

ho provato diverse cose, più di recente:

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

avrei dovuto usare qualcosa come:

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

Tirando fuori i miei capelli qui ... tutti i pensieri?

+0

Hai provato: 'var coordinate = UnsafeMutablePointer ()'? –

+0

Purtroppo, sì. Risultati in: ''UnsafeMutablePointer ' non è identico a 'CLLocationCoordinate2D'' Che non ha alcun senso per me dato che dovrebbe essere' UnsafeMutablePointer ' nella funzione. –

+0

Non ho un errore del compilatore con 'var coordinates = [CLLocationCoordinate2D]()', ma la funzione 'getCoordinates' non restituisce nulla a' & coordinate' –

risposta

46

Normalmente si può semplicemente passare un array del tipo richiesto come parametro in-out, alias

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

ma che la documentazione fa sembrare come una cattiva idea! Per fortuna, UnsafeMutablePointer fornisce un metodo statico alloc(num: Int), in modo da poter chiamare getCoordinates() in questo modo:

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

Per ottenere l'attuale CLLocationCoordinate2D oggetti fuori dal puntatore mutevole, si dovrebbe essere in grado di appena scorrere:

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

E dal momento che non si vuole una perdita di memoria, finire in questo modo:

coordsPointer.dealloc(polyline.pointCount) 

appena ricordato Array ha un metodo reserveCapacity() esempio, quindi una (e probabilmente più sicuro) versione molto più semplice di questo potrebbe essere:

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

Chi sei e perché non siamo i migliori amici. –

+13

Ehi, sono qui e tutto, ma non chiami mai. –

+1

Ho ancora una domanda: PERCHÉ l'API continuerà a utilizzare 'UnsafeMutablePointer' invece di un buon vecchio 'swift ottimizzato? Sembra un grande sforzo aggiuntivo per niente. –

0

estensione wrapper per la risposta impressionante di @Nate Cook, non è possibile ottenere la versione reserveCapacity() al lavoro , continua a restituire oggetti vuoti.

import MapKit 

extension MKPolyline { 

    var coordinates: [CLLocationCoordinate2D] { 
     get { 
      let coordsPointer = UnsafeMutablePointer<CLLocationCoordinate2D>.allocate(capacity: pointCount) 
      var coords: [CLLocationCoordinate2D] = [] 
      for i in 0..<pointCount { 
       coords.append(coordsPointer[i]) 
      } 
      coordsPointer.deallocate(capacity: pointCount) 
      return coords 
     } 
    } 
} 
Problemi correlati