サイズのC配列を取るために使用されたSwiftの関数とどのように対話できますか?
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)))
ここで髪を抜く...何か考えはありますか?
通常、必要なタイプの配列をin-outパラメータとして渡すことができます。
_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))
_
@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
}
}
}