UnsafeMutablePointer in swift as replacement for properly sized C Array in Obj-C

喜你入骨 提交于 2019-11-30 04:49:06

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
        }
    }
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!