【问题标题】:Alamofire request gives memory warningAlamofire 请求给出内存警告
【发布时间】:2016-03-31 08:20:53
【问题描述】:

我正在使用主从应用程序。主屏幕是一个仪表板,在选择一个项目时,移动到我在后端触发 Alamofire 请求的详细屏幕

下面是sn-p

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() 中,我还取消了任何正在进行的请求。但我无法停止内存警告问题。我评论了我调用请求的部分,我没有看到任何问题,甚至内存消耗也更少。

我欢迎提出想法。

【问题讨论】:

    标签: ios swift memory-management memory-leaks alamofire


    【解决方案1】:

    问题是您永远不会删除附加到成员变量“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)
        }
    

    在 Array 上添加这个 Handy 扩展以将项目删除到您的代码中:

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

    【讨论】:

      【解决方案2】:

      经过分析,我发现内存警告不是由于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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-12-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-02
        相关资源
        最近更新 更多