swiftify objective objc for convert swift mkpolyline

objective - UnsafeMutablePointer en swift como reemplazo para una matriz C del tamaño adecuado en Obj-C



swift to objective c (2)

Normalmente, solo puede pasar una matriz del tipo requerido como un parámetro de entrada-salida, también conocido como

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

¡Pero esa documentación hace que parezca una mala idea! Afortunadamente, UnsafeMutablePointer proporciona un alloc(num: Int) estática alloc(num: Int) , por lo que puede llamar a getCoordinates() siguiente manera:

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

Para obtener los objetos CLLocationCoordinate2D reales fuera del puntero mutable, debería poder simplemente realizar un bucle a través de:

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

Y como no quieres una pérdida de memoria, termina así:

coordsPointer.dealloc(polyline.pointCount)

Acabo de recordar que Array tiene un método de instancia reserveCapacity() , por lo que una versión mucho más simple (y probablemente más segura) sería:

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

¿Cómo puedo interactuar con las funciones de Swift que solían tomar matrices de tamaño C?

Leí Interactuar con C APIS y todavía no puedo resolver esto.

La documentación para el parámetro coords de func getCoordinates(_ coords:UnsafeMutablePointer<CLLocationCoordinate2D>,range range: NSRange) indica: "En la entrada, debe proporcionar un conjunto de C de estructuras lo suficientemente grande como para contener el número deseado de coordenadas. En la salida, esta estructura contiene los datos de coordenadas solicitados ".

Probé varias cosas, la más reciente:

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

¿Tendría que usar algo como:

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

Sacándome el pelo aquí ... ¿alguna idea?


la envoltura de extensión para la asombrosa respuesta de @Nate Cook, no puede hacer que reserveCapacity() versión reserveCapacity() , sigue devolviendo el objeto vacío.

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 } } }