I noticed, by running on various simulators, IOS 13.7 does not have the problem but 14.0, 14.1 and 14.2 do.
here is the code to reproduce
//
// ViewController.swift
// ios14PolylineMemoryLeak
//
// Created by Henri on 26/11/2020.
//
import UIKit
import MapKit
class ViewController: UIViewController, MKMapViewDelegate {
//
// to see reproduction run instruments/leaks
// - it will report leaks on IOS 14.2 and memory usage is increasing all the time.
// - On IOS 13.7 all is ok, no memory leaks, and memory usage remains at a contant value
//
// Below out that Instruments Leaks is giving me.
// Malloc 144 Bytes 111 < multiple > 15,61 KiB
// VectorKit geo::MallocZoneAllocator::allocate(unsigned long, unsigned long)
// MTLSimTexture 81 < multiple > 30,38 KiB
// MTLSimDriver_77-[MTLSimTexture newTextureViewWithPixelFormatInternal:isInternalTextureView:]blockinvoke
// Malloc 16 Bytes 93 < multiple > 1,45 KiB
// VectorKit geo::MallocZoneAllocator::allocate(unsigned long, unsigned long)
//
//
@IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
setupMapView()
reproduceIos14PolylineMemoryLeak()
}
func reproduceIos14PolylineMemoryLeak() {
= Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(fireTimer), userInfo: nil, repeats: true)
}
@objc func fireTimer() {
let coordinate1 = mapView.convert(CGPoint(x: 100, y: 100), toCoordinateFrom: mapView)
let coordinate2 = mapView.convert(CGPoint(x: 300, y: 300), toCoordinateFrom: mapView)
let farawayCoordinate = locationWithBearing(bearing: 90, distanceMeters: 50000, origin: coordinate2)
var coordinates = [CLLocationCoordinate2D]()
coordinates.append(coordinate1)
coordinates.append(coordinate2)
coordinates.append(farawayCoordinate)
let polyline = MKPolyline(coordinates: coordinates, count: coordinates.count)
let overlays = mapView.overlays
for overlay in overlays {
mapView.removeOverlay(overlay)
}
mapView.addOverlay(polyline)
}
func locationWithBearing(bearing:Double, distanceMeters:Double, origin:CLLocationCoordinate2D) -> CLLocationCoordinate2D {
let distRadians = distanceMeters / (6372797.6)
let rbearing = bearing * Double.pi / 180.0
let lat1 = origin.latitude * Double.pi / 180
let lon1 = origin.longitude * Double.pi / 180
let lat2 = asin(sin(lat1) * cos(distRadians) + cos(lat1) * sin(distRadians) * cos(rbearing))
let lon2 = lon1 + atan2(sin(rbearing) * sin(distRadians) * cos(lat1), cos(distRadians) - sin(lat1) * sin(lat2))
return CLLocationCoordinate2D(latitude: lat2 * 180 / Double.pi, longitude: lon2 * 180 / Double.pi)
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if (overlay is MKPolyline)
{
let renderer = MKPolylineRenderer(overlay: overlay)
renderer.strokeColor = .systemBlue
renderer.lineWidth = 5.0
return renderer
}
return MKOverlayRenderer(overlay: overlay)
}
func setupMapView() {
let appleCoordinate = CLLocation(latitude: 37.33182, longitude: -122.03118)
mapView.delegate = self
let coordinateRegion = MKCoordinateRegion(
center: CLLocationCoordinate2D(
latitude: appleCoordinate.coordinate.latitude,
longitude: appleCoordinate.coordinate.longitude),
latitudinalMeters: 10 ,
longitudinalMeters: 1000)
mapView.setRegion(coordinateRegion, animated: true)
}
}