Mapkit is using too much CPU in IOS 13

我的未来我决定 提交于 2019-12-07 19:47:49

问题


Recently my iOS app starting crashing frequently after some users updated to iOS 13.x (it doesn't exhibit the problem in iOS 12.x)

I am using Mapkit to render some MKPolygons and MKPolylines.

The MKPolylines get removed and re-added to the MKMapView around 10 times per second (that's because my GPS is giving me new lat/longs at 10Hz).

I profiled my app in iOS 12.x and it is using around 15% to 30% of CPU resources (iPad Mini 4).

I did the same profiling in iOS 13.1.2 and 13.1.3, and the CPU consumption went up to around 150% (there are 2 CPU cores).

If I remove the code that renders the 2 MKPolylines at 10Hz, the CPU utilization goes back down to iOS 12.x levels.

In iOS 13.x my app is being killed by iOS, and in the crash logs it reports the reason as something like: CPU is exceeding X% for over Y seconds.

Here is the code that adds and removes the two MKPolyLines:

 func updateLinesToField(myLocation: CLLocationCoordinate2D, field : Site) {
        guard let field = State.shared.currentField else {
            return
        }

        if let _ = closestPassPoint {
            if passLine != nil {
                //calls MKMapView's removeOverlay method
                mapView.remove(passLine)
            }
            if field.state != .completed && myLocation.distanceTo(closestPassPoint) <= Settings.shared.passExtensionLengthMeters {
                passLine = StyledPolyLine(coordinates: [myLocation, closestPassPoint], count: 2)
                passLine.styleAsLineToPass()
                //calls MKMapView's addOverlay method
                mapView.add(passLine)
            }
        }

        if routeLine != nil {
            //calls MKMapView's removeOverlay method
            mapView.remove(routeLine)
        }

        if Settings.shared.showLineToField == .show && field.state != .completed {

            guard State.shared.currentField.passes != nil else {
                return
            }

            let currentPassIndex = State.shared.clipPassIndex()
            let currentPass = State.shared.currentField.passes[currentPassIndex]

            if let nearestPassCoords = currentPass.approachPoints {
                let dist0 = State.shared.currentLocation.distanceTo(nearestPassCoords[0])
                let dist1 = State.shared.currentLocation.distanceTo(nearestPassCoords[1])
                if dist0 < dist1 {
                    routeLine = StyledPolyLine(coordinates: [myLocation, nearestPassCoords[0]], count: 2)
                } else {
                    routeLine = StyledPolyLine(coordinates: [myLocation, nearestPassCoords[1]], count: 2)
                }
                routeLine.styleAsLineToField()
                //calls MKMapView's addOverlay method
                mapView.add(routeLine)
            }
        }
    }

And StyledPolyLine just inherits from MKPolyline:

class StyledPolyLine: MKPolyline {
    var strokeColor: UIColor!
    var lineWidth: CGFloat! // defaults to 0, which is MKRoadWidthAtZoomScale(currentZoomScale)
    var lineDashPattern: [NSNumber]! // defaults to nil


    func renderer() -> MKPolylineRenderer {
        let _renderer = MKPolylineRenderer(overlay: self)
        _renderer.strokeColor = self.strokeColor
        _renderer.lineWidth = self.lineWidth
        _renderer.lineDashPattern = self.lineDashPattern
        /*
        if #available(iOS 13.0, *) {
            _renderer.shouldRasterize = true
        }
         */
        return _renderer
    }
}

Note that I tried changing the shouldRasterize parameter to true and it had no effect on CPU utilization.

Any ideas how I can get my CPU usage back down to iOS 12.x levels?

来源:https://stackoverflow.com/questions/58441184/mapkit-is-using-too-much-cpu-in-ios-13

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!