swift中的UnsafeMutablePointer替换Obj-C中正确大小的C数组

时间:2014-08-29 02:17:13

标签: swift mkpolyline

我如何与swift中的函数进行交互,这些函数曾经用于获取大小的C数组?

我通过Interacting with C APIS阅读,但仍无法解决这个问题。

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

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

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

我是否必须使用以下内容:

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

把头发拉出来......有什么想法吗?

2 个答案:

答案 0 :(得分:49)

通常,您只需将所需类型的数组作为输入输出参数传递,即

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

答案 1 :(得分: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
        }
    }
}