MapView Memory Leak ?

I have created a simple project with 2 view controllers. The first VC just has one button, that segue to the second VC. The second VC has an MKMapView and a back button.


I have put print statements into the VC lifecycle events to more easily track what is happening.


The problem is, when I return to the first VC, by hitting the back button in the second VC, a significant chunk of memory is not returned.


I have tried the memoryHotfix several other users indicated worked in earlier versions of Xcode - but this is not working - (changing mapView type, setting delegate and mapView to nil).


I can confirm the second VC is calling the deinit function (see debug trace)


@IBAction func btnShowMap(_ sender: UIBarButtonItem) {

     print("********* MainVC \(#function) **********")

     performSegue(withIdentifier: "showMap", sender: nil) self.dismiss(animated: true, completion: {})

}


override func viewDidLoad() {

     print("********* MainVC \(#function) **********")

     super.viewDidLoad()

}


override func didReceiveMemoryWarning()
{

print("********* MainVC \(#function) **********")

     super.didReceiveMemoryWarning()

}


override func viewWillDisappear(_ animated: Bool)
{

print ("********* MainVC \(#function) ********** ")

}

override func viewDidDisappear(_ animated: Bool) {

print ("********* MainVC \(#function) ********** ")

}

override func viewDidAppear(_ animated: Bool) {

print ("********* MainVC \(#function) ********** ")

}

override func viewWillAppear(_ animated: Bool) {

print ("********* MainVC \(#function) ********** ")

}

deinit {

print ("********* MainVC \(#function) ********** ")

}

here is the code for the second (Map) VC -


class MapVC: UIViewController, MKMapViewDelegate {


@IBOutlet weak var mapView: MKMapView!


@IBAction func btnBack(_ sender: UIButton) {

     self.dismiss(animated: true, completion: {})

}


override func viewDidLoad() {

     print("********* MapVC \(#function) **********")

     super.viewDidLoad()

     print (" mapView.delegate = self")

     self.mapView.delegate = self

}


override func didReceiveMemoryWarning() {

     print("********* MapVC \(#function) **********")

     super.didReceiveMemoryWarning()

}


func removeNastyMapMemory() {

     print (" ********* MapVC \(#function) ********** ")


     if mapView != nil {

          switch mapView.mapType {

          case .hybrid :

               print (" mapType = MKMapType.standard")

               mapView.mapType = MKMapType.standard

          case .standard:

               print (" mapType = MKMapType.hybrid")

               mapView.mapType = MKMapType.hybrid

          default:

               print (" mapType = ???")

               break

          }


          print (" showsUserLocation = false")

          mapView.showsUserLocation = false


          if mapView.delegate != nil {

               print (" mapView.delegate = nil")

               mapView.delegate = nil

          }

         

          print (" mapView = nil")

          mapView.removeFromSuperview() mapView = nil

     }

}


override func viewWillDisappear(_ animated: Bool) {

     print ("********* MapVC \(#function) ********** ")

     removeNastyMapMemory()

}


override func viewDidDisappear(_ animated: Bool) {

     print ("********* MapVC \(#function) ********** ")

}


override func viewDidAppear(_ animated: Bool) {

     print ("********* MapVC \(#function) ********** ")

}


override func viewWillAppear(_ animated: Bool) {

     print ("********* MapVC \(#function) ********** ")

}


deinit {

     print ("********* MapVC \(#function) ********** ")

}


here is the output debug trace -


********* MainVC viewDidLoad() **********

********* MainVC viewWillAppear **********

********* MainVC viewDidAppear **********

********* MapVC viewDidLoad() **********

mapView.delegate = self

********* MainVC viewWillDisappear **********

********* MapVC viewWillAppear **********

********* MapVC viewDidAppear **********

********* MainVC viewDidDisappear **********

********* MapVC viewWillDisappear **********

********* MapVC removeNastyMapMemory() **********

mapType = MKMapType.hybrid

showsUserLocation = false

mapView.delegate = nil

mapView = nil

********* MainVC viewWillAppear **********

********* MainVC viewDidAppear **********

********* MapVC viewDidDisappear **********

********* MapVC deinit **********

********* MapVC viewDidLoad() **********

mapView.delegate = self

********* MainVC viewWillDisappear **********

********* MapVC viewWillAppear **********

********* MapVC viewDidAppear **********

********* MainVC viewDidDisappear **********

********* MapVC viewWillDisappear **********

********* MapVC removeNastyMapMemory() **********

mapType = MKMapType.hybrid

showsUserLocation = false

mapView.delegate = nil

mapView = nil

********* MainVC viewWillAppear **********

********* MainVC viewDidAppear **********


....this continues as many times as you push the Map and Back buttons

and here is the memory usage just keeps going up and up.


Am I missing something here - or doing something wrong ?

Or is this a memory leak and I should raise a radar ?


Any help appreciated


Info :

Xcode Version 8.3 beta (8W109m)

Mac OS Sierra Version 10.12.3

    

Replies

Hi,


ive spotted this problem too -> on simulator and real device.


My app on startup takes about 30mb of memory, after loading up and dismissing view with map kit (and button to dismiss), memory usage grows at least x4 and it doesnt drop below 80mb (never). Instruments shows huge amount of VectorKit leaks on simulator


PS1. all 'mine' allocations within map kit view controller are released properly

PS2. during my observation i saw that if you dont remove annotations, overlays etc. manually then the amount of heap is bigger and grows faster

PS3. ive tried to use shared mapkit view and reuse it throughout my app -> didnt help much.

PS4. Xcode 8.1, Simulator is on 10.1, device on 10.0.1


Let me know if you find out anything

Cheers

Hi,

I am facing the same problem recently. Did you figure out what's the issue? Is it a MapKit bug?

Did you file a bug report ?