19

如何在 swift 中与用于获取大小 C 数组的函数进行交互?

我通读了与 C APIS 交互,但仍然无法弄清楚。

状态的 coords 参数的文档func getCoordinates(_ coords:UnsafeMutablePointer<CLLocationCoordinate2D>,range range: NSRange):“在输入时,您必须提供一个足够大的 C 结构数组以容纳所需数量的坐标。在输出时,此结构包含请求的坐标数据。”

我尝试了几件事,最近一次:

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

我是否必须使用类似的东西:

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

把我的头发拉在这里......有什么想法吗?

4

2 回答 2

50

通常,您可以将所需类型的数组作为输入输出参数传递,也就是

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

但是该文档使它看起来像个坏主意!幸运的是,UnsafeMutablePointer提供了一个静态alloc(num: Int)方法,所以你可以这样调用getCoordinates()

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

要从可变指针中获取实际CLLocationCoordinate2D对象,您应该能够遍历:

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

并且由于您不想要内存泄漏,因此可以这样完成:

coordsPointer.dealloc(polyline.pointCount)

刚刚记得Array有一个reserveCapacity()实例方法,所以一个更简单(可能更安全)的版本是:

var coords: [CLLocationCoordinate2D] = []
coords.reserveCapacity(polyline.pointCount)
polyline.getCoordinates(&coords, range: NSMakeRange(0, polyline.pointCount))
于 2014-08-29T03:03:04.013 回答
0

@Nate Cook 很棒的答案的扩展包装器,无法使reserveCapacity()版本正常工作,它一直返回空对象。

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
        }
    }
}
于 2017-05-25T08:25:46.680 回答