How can I interact with functions in swift that used to take sized C arrays?
I read through Interacting with C APIS and still can't figure this out.
The documentation for the coords parameter of func getCoordinates(_ coords:UnsafeMutablePointer<CLLocationCoordinate2D>,range range: NSRange)
states: "On input, you must provide a C array of structures large enough to hold the desired number of coordinates. On output, this structure contains the requested coordinate data."
I tried several things, most recently:
var coordinates: UnsafeMutablePointer<CLLocationCoordinate2D> = nil
polyline.getCoordinates(&coordinates, range: NSMakeRange(0, polyline.pointCount))
Would I have to use something like:
var coordinates = UnsafeMutablePointer<CLLocationCoordinate2D>(calloc(1, UInt(polyline.pointCount)))
Pulling my hair out here... any thoughts?
Normally you can just pass an array of the required type as an in-out parameter, aka
var coords: [CLLocationCoordinate2D] = []
polyline.getCoordinates(&coords, range: NSMakeRange(0, polyline.pointCount))
but that documentation makes it seem like a bad idea! Luckily, UnsafeMutablePointer
provides a static alloc(num: Int)
method, so you can call getCoordinates()
like this:
var coordsPointer = UnsafeMutablePointer<CLLocationCoordinate2D>.alloc(polyline.pointCount)
polyline.getCoordinates(coordsPointer, range: NSMakeRange(0, polyline.pointCount))
To get the actual CLLocationCoordinate2D
objects out of the mutable pointer, you should be able to just loop through:
var coords: [CLLocationCoordinate2D] = []
for i in 0..<polyline.pointCount {
coords.append(coordsPointer[i])
}
And since you don't want a memory leak, finish up like so:
coordsPointer.dealloc(polyline.pointCount)
Just remembered Array
has a reserveCapacity()
instance method, so a much simpler (and probably safer) version of this would be:
var coords: [CLLocationCoordinate2D] = []
coords.reserveCapacity(polyline.pointCount)
polyline.getCoordinates(&coords, range: NSMakeRange(0, polyline.pointCount))
extension wrapper for @Nate Cook's awesome answer, cannot get the reserveCapacity()
version to work, it keep returning empty object.
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
}
}
}
来源:https://stackoverflow.com/questions/25560751/unsafemutablepointer-in-swift-as-replacement-for-properly-sized-c-array-in-obj-c