2016-03-31 47 views
0

我正在使用主控细节应用程序。主屏幕是一块仪表盘和选择项目,移动到详细屏幕,我在后台Alamofire请求会给出内存警告

低于触发Alamofire请求片断

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) 
    } 
} 

我有一个单独的API管理器类,并从详细视图控制器我称之为getData()函数。一切正常。

但是,当我重复推动和弹出时,我看到内存迅速增加,并且在10-15次尝试后,我收到内存警告。但在AppDelegate我管理它显示一条警报消息并添加一个延迟计时器8秒。但是,20-25尝试应用程序崩溃后,由于内存警告。

viewWillDisappear(),我也取消了任何正在进行的请求。但我无法停止记忆警告问题。我评论了我称之为请求的部分,我没有发现问题,即使内存消耗也较少。

我欢迎创意。

回答

0

上分析,我发现内存警告是不是由于Alamofire请求。这是由于MKMapView。加载MKMapView,放大和缩小消耗更多内存。所以,在viewWillDisappear我做了修复。

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 
} 

礼貌 - Stop iOS 7 MKMapView from leaking memory

0

问题是你永远不会删除你追加到成员变量'requests'的请求。

当您取消请求或请求成功完成时,您需要确保删除请求。

请执行以下变通

func cancelRequests() { 
     if requests.count > 0 { 
      for request in requests { 
       request.cancel() 
      } 
     } 
     requests.removeAll() //Delete all canseled requests 
    } 

also 

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) 
          } 
          requests.removeObject(request) 
          completion(dataSet: dataSet, error: nil) 
         } 
        } else { 
         requests.removeObject(request) 
         completion(dataSet: nil, error: error) } 
       }) 
     } 
     requests.append(request) 
    } 

加入这个方便扩展的阵列删除项目代码:

// Swift 2 Array Extension 
extension Array where Element: Equatable { 
    mutating func removeObject(object: Element) { 
     if let index = self.indexOf(object) { 
      self.removeAtIndex(index) 
     } 
    } 

    mutating func removeObjectsInArray(array: [Element]) { 
     for object in array { 
      self.removeObject(object) 
     } 
    } 
}