You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何高效绘制动态更新的MKPolyline?解决内存占用过高问题

问题根源

你当前代码的核心问题是重复添加MKPolyline Overlay:每次收到新坐标时,都基于完整的路径数组创建新的MKPolyline,并调用addOverlay添加到地图。30分钟后,地图上会叠加约1800条完全重合的Polyline,每条都需要独立渲染,直接导致CPU占用飙升、内存溢出和卡顿。

解决方案:维护单条Polyline并高效更新

只保留一条MKPolyline实例,每次新增坐标后,通过replaceOverlay方法替换旧的Polyline,而非重复添加新的Overlay。这样地图始终只渲染一条路径,彻底解决资源占用问题。

修改后的ViewController代码

var polyline: MKPolyline?

override func viewDidLoad() {
    super.viewDidLoad()
    setupBindings()
    mapView.delegate = self
    mapView.addAnnotation(viewModel.aircraftLocation)
}

func setupBindings() {
    viewModel.$simulationData.sink { [weak self] simData in
        guard let simData, let self else { return }
        DispatchQueue.main.async {
            // 更新经纬度显示标签
            self.LatitudeLbl.text = String(format: "Lat: %.5f", simData.latitude)
            self.longitudeLbl.text = String(format: "Long: %.5f", simData.longitude)
            
            // 基于最新路径数组创建新的Polyline
            let newPolyline = MKPolyline(coordinates: &self.viewModel.aircraftPath, count: self.viewModel.aircraftPath.count)
            
            if let oldPolyline = self.polyline {
                // 替换旧Overlay,避免重复叠加
                self.mapView.replaceOverlay(oldPolyline, with: newPolyline)
            } else {
                // 首次添加路径Overlay
                self.mapView.addOverlay(newPolyline)
            }
            self.polyline = newPolyline
        }
    }.store(in: &viewModel.subscriptions)
}

func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
    guard let polylineOverlay = overlay as? MKPolyline else {
        return MKOverlayRenderer()
    }
    let renderer = MKPolylineRenderer(polyline: polylineOverlay)
    renderer.strokeColor = .purple
    renderer.lineWidth = 2
    return renderer
}

ViewModel代码(无需核心修改)

@Published public var simulationData: SimulationData?

func didReceiveSimulationUpdate(simulation: SimulationData) {
    // 将新坐标追加到路径数组
    aircraftPath.append(simulation.aircraft.location)
    
    DispatchQueue.main.async {
        UIView.animate(withDuration: 0.3) {
            self.simulationData = simulation
            self.aircraftLocation.coordinate = simulation.aircraft.location
        }
    }
}
额外优化建议
  1. 坐标去重:如果连续收到的坐标距离极近(比如小于1米),可以跳过添加,减少路径数组长度和Polyline更新次数。
  2. 批量更新:若每秒一次更新过于频繁,可改为每2-3秒合并一次坐标再刷新路径,降低地图渲染压力。
  3. 路径截断:如果不需要保留完整历史路径,可限制路径数组长度(比如只保留最近1000个点),避免数组无限增长导致的内存占用。

内容的提问来源于stack exchange,提问作者Fred Novack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 14:52:56