Search code examples
iosswiftmemory-managementmemory-leaksalamofire

Alamofire request gives memory warning


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.


Solution

  • 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