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

前端 未结 2 521
春和景丽
春和景丽 2020-12-29 06:12

How can I interact with functions in swift that used to take sized C arrays?

I read through Interacting with C APIS and still can\'t figure this out.

The doc

相关标签:
2条回答
  • 2020-12-29 06:38

    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
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-29 06:43

    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))
    
    0 讨论(0)
提交回复
热议问题