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

And*_*son 18 mkpolyline swift

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

我阅读了与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))
Run Code Online (Sandbox Code Playgroud)

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

var coordinates = UnsafeMutablePointer<CLLocationCoordinate2D>(calloc(1, UInt(polyline.pointCount)))
Run Code Online (Sandbox Code Playgroud)

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

Nat*_*ook 49

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

var coords: [CLLocationCoordinate2D] = []
polyline.getCoordinates(&coords, range: NSMakeRange(0, polyline.pointCount))
Run Code Online (Sandbox Code Playgroud)

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

var coordsPointer = UnsafeMutablePointer<CLLocationCoordinate2D>.alloc(polyline.pointCount)
polyline.getCoordinates(coordsPointer, range: NSMakeRange(0, polyline.pointCount))
Run Code Online (Sandbox Code Playgroud)

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

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

因为你不想要内存泄漏,所以完成如下:

coordsPointer.dealloc(polyline.pointCount)
Run Code Online (Sandbox Code Playgroud)

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

var coords: [CLLocationCoordinate2D] = []
coords.reserveCapacity(polyline.pointCount)
polyline.getCoordinates(&coords, range: NSMakeRange(0, polyline.pointCount))
Run Code Online (Sandbox Code Playgroud)

  • 嘿,我在这里,除了你从来没有打过电话. (13认同)
  • 你是谁?为什么我们不是最好的朋友. (10认同)
  • 那个数组只是一个坏主意,因为它不够大.如果你创建了一个足够大小的数组,例如`var coords:[CLLocationCoordinate2D] = [CLLocationCoordinate2D](count:polyline.pointCount,repeatedValue:kCLLocationCoordinate2DInvalid)`那么我不明白你为什么不能通过` &coords`直接作为指针. (4认同)
  • @AndrewRobinson:API是从Objective-C导入的,类型是以自动方式翻译的.Objective-C签名是` - (void)getCoordinates:(CLLocationCoordinate2D*)coords范围:(NSRange)range`.在C中,你不能传递一个数组,只能传递一个指针(加上,C是传值,所以它无论如何都不会起作用,因为我们需要能够修改数组的函数).指针没有相关的大小.另外,在C中,您无法调整已分配的数组的大小.在Cocoa中有NSMutableArray,但这需要作为对象的元素,而CLLocationCoordinate2D则不是. (2认同)
  • 使用`defer`作为`dealloc`也很好:`var startCoordinates:UnsafeMutablePointer <CLLocationCoordinate2D> = UnsafeMutablePointer.alloc(step.polyline.pointCount)defer {startCoordinates.dealloc(step.polyline.pointCount)}` (2认同)