I am using a Master Detail Application. Master Screen is a Dashboard and on selecting an item, moves to the detailed screen where I trigger an Alamofire
request in the backend
Below is the snippet
class APIManager: NSObject {
class var sharedManager: APIManager {
return _sharedManager
}
private var requests = [Request]()
// Cancel any ongoing download
func cancelRequests() {
if requests.count > 0 {
for request in requests {
request.cancel()
}
}
}
func getData(completion: (dataSet: [Data]?, error: NSError?) -> Void) {
let request = Alamofire.request(.GET, "http://request")
.response { (request, response, data, error) in
dispatch_async(dispatch_get_main_queue(), {
if(error == nil) {
if let response = data, data = (try? NSJSONSerialization.JSONObjectWithData(response, options: [])) as? [NSDictionary] {
var dataSet = [Data]()
for (_, dictionary) in data.enumerate() {
let lat = dictionary["Latitude"]
let lng = dictionary["Longitude"]
let id = dictionary["ID"] as! Int
let data = Data(lat: lat!, long: lng!, id: shuttleID)
dataSet.append(data)
}
completion(dataSet: dataSet, error: nil)
}
} else { completion(dataSet: nil, error: error) }
})
}
requests.append(request)
}
}
I have a singleton API manager class and from the detail view controller I call getData()
function. Everything works fine.
But, when I push and pop repeatedly, I see rapid increase in the memory and after 10-15 attempts, I get memory warning. However in the AppDelegate
I am managing it to show an Alert message and adding a delay timer for 8 seconds. But however after 20-25 attempts app crashes due to memory warning.
In viewWillDisappear()
, I cancel any ongoing requests also. But I couldn't able to stop memory warning issue. I commented the part where I call the request, I see no issues, even memory consumption is less.
I welcome ideas.
On analysis, I found that the memory warning was not due to the Alamofire
request. It was due to MKMapView
. Loading a MKMapView
, zooming in and zooming out consumes more memory. So, in viewWillDisappear
I did the fix.
override func viewWillDisappear(animated:Bool){
super.viewWillDisappear(animated)
self.applyMapViewMemoryFix()
}
func applyMapViewMemoryFix(){
switch (self.mapView.mapType) {
case MKMapType.Hybrid:
self.mapView.mapType = MKMapType.Standard
break;
case MKMapType.Standard:
self.mapView.mapType = MKMapType.Hybrid
break;
default:
break;
}
self.mapView.showsUserLocation = false
self.mapView.delegate = nil
self.mapView.removeFromSuperview()
self.mapView = nil
}
Courtesy - Stop iOS 7 MKMapView from leaking memory