【问题标题】:Alamofire memory leaks InstrumentsAlamofire 内存泄漏 Instruments
【发布时间】:2017-05-26 10:40:46
【问题描述】:

我正在尝试从内存泄漏中清除我的应用程序,但我在理解这一点时遇到了一些问题

  • 为什么在我启动应用程序 30 秒后调用 Alamofire 函数 Request.serializeResponseJSON:我没有触摸任何东西或导航任何地方,屏幕是静态的。

  • 为什么会泄漏?

  • 为什么我的代码会泄露?

屏幕加载后我也会出现同样的泄漏。

到目前为止我已经尝试过:

  • 自动释放池;

  • 以各种可能的方式附加和初始化数组;

  • 将所有变量(类、函数)更改为可选/不可选 可选/弱;

  • 初始化UIViewController中的类;

  • 在主线程中初始化类;

  • 在网上搜索这些问题。

  • 我发现,使用 Xcode 内存工具,它以某种方式与 _ContiguousArrayStorage 连接,但我不明白它是如何以及它实际上是什么。

我不知道这里出了什么问题。任何提示将不胜感激。

以下是所有相关代码: 我的一般 API 请求

public func requestWithLocation(_ httpmethod: Alamofire.HTTPMethod, URL: String, parameters: [String: AnyObject]?, completionHandler: @escaping CompletionHandler) -> (){
    var header: HTTPHeaders = [:]
    var location: [String: Double] = [:]
    let locationManager = CLLocationManager()

    if (CLLocationManager.authorizationStatus() == .authorizedWhenInUse
        || CLLocationManager.authorizationStatus() == .authorizedAlways) &&  locationManager.location != nil {
        location = [
            "lon" :  locationManager.location!.coordinate.longitude,
            "lat" :  locationManager.location!.coordinate.latitude
        ]
    }

    if User.sharedInstance.token != "" {
        header["Authorization"] = User.sharedInstance.token
    }

    var parametersWithLocation = parameters ?? [:]
    parametersWithLocation["location"] = location as AnyObject

    Alamofire.request("\(serverAddress)/\(URL)", method: httpmethod, parameters: parametersWithLocation, encoding: JSONEncoding.default, headers: header).validate().responseJSON { response in
        var data: JSON?

        if response.result.value != nil {
            data = JSON(response.result.value!)
        }
        if User.sharedInstance.token == "" {
            User.sharedInstance.token =  response.response?.allHeaderFields["Authorization"] as! String
        } else {
            if let header = response.response?.allHeaderFields["Authorization"] as? String {
                if User.sharedInstance.token != header {
                    User.sharedInstance.token = header
                }
            }
        }
        completionHandler(data, response.result.error as NSError?)
    }
}

我的屏幕请求

class func requestMainScreen(handler: @escaping ([ShortRestaurant], [ShortRestaurant], [ShortRestaurant]) -> ()) {
    var dataForBestChoise: [ShortRestaurant] = []
    var dataForTop: [ShortRestaurant] = []
    var dataForNearest: [ShortRestaurant] = []

    let group = DispatchGroup()
    group.enter()

    APIModel.sharedInstance.requestWithLocation(.post, URL: "restaurants/near", parameters: nil, completionHandler: {(data, error) in

        guard let `data` = data else {
            group.leave()
            return
        }
        for JSON in data["restaurants"].arrayValue {
            dataForNearest.append(ShortRestaurant.initFromJSON(JSON)) //here is leak
        }
        group.leave()
    })

    group.enter()
    APIModel.sharedInstance.requestWithLocation(.post, URL: "restaurants/top", parameters: nil, completionHandler: {(data, error) in
        guard let `data` = data else {
            group.leave()
            return
        }
        for JSON in data["restaurants"].arrayValue {
            dataForTop.append(ShortRestaurant.initFromJSON(JSON))//here is leak
        }
        group.leave()
    })

    group.enter()
    APIModel.sharedInstance.requestWithLocation(.post, URL: "restaurants/personal", parameters: nil, completionHandler: {(data, error) in

        guard let `data` = data else {
            group.leave()
            return
        }

        for JSON in data["restaurants"].arrayValue {
             dataForBestChoise.append(ShortRestaurant.initFromJSON(JSON)) //here is leak
        }
        group.leave()
    })

    group.notify(queue: DispatchQueue.main) {
        handler(dataForBestChoise, dataForTop, dataForNearest)
    }
}

我的课程(我知道这种初始化有点错误,但我已更改为 init(data: JSON) - 没有帮助:

class func initFromJSON(_ data: JSON) -> ShortRestaurant {
    let restaurant = ShortRestaurant()
    restaurant.id                       = data["id"].stringValue
    restaurant.name                     = data["name"].stringValue
    restaurant.image                    = data["img"].stringValue
    restaurant.description              = data["shortDesc"].stringValue
    restaurant.nameOfMetrostatin        = data["address"]["metro"]["name"].stringValue
    restaurant.mapType                  = data["mapType"].stringValue
    restaurant.address                  = data["address"]["street"].stringValue
    restaurant.longitude                = data["address"]["location"][0].doubleValue
    restaurant.latitude                 = data["address"]["location"][1].doubleValue
    restaurant.phone                    = data["phone"].stringValue
    restaurant.workTime                 = data["currentWork"].stringValue
    restaurant.avarageBill              = data["price"].stringValue
    restaurant.peopleInfo               = data["croud"].stringValue
    restaurant.rating                   = data["rating"].stringValue
    restaurant.ratingTrend              = data["trend"].stringValue
    restaurant.distance                 = data["distance"].doubleValue
    restaurant.isFavourited             = data["isFavourited"].bool ?? false
    restaurant.specialOfferDescription  = data["discounts"]["name"].string
    restaurant.specialOfferName         = data["discounts"]["type"].string
    restaurant.alertText                = data["label"]["name"].string
    restaurant.alertIcon                = data["label"]["type"].string
    restaurant.alertBackground          = data["label"]["color"].string
    restaurant.avaliableDates           = ReservationSchedule.initArrayFrom(data: data["availableDates"])
    restaurant.avaliableTimes           = data["scheduleRes"].arrayObject as? [String] ?? []
    restaurant.doesHaveDiscount         = data["discounts"]["id"].string != nil
    restaurant.doesHaveEvent            = data["events"]["id"].string != nil
    restaurant.weeklyTop                = data["weeklyTop"].bool ?? false
    restaurant.monthlyTop               = data["monthlyTop"].bool ?? false
    restaurant.yearTop                  = data["yearTop"].bool ?? false
    restaurant.isActive                 = data["isActive"].bool ?? true
    return restaurant
}

这些泄漏的数组:

class ReservationSchedule {
  var description: String
  var data: String
  var dayTitle: String
  var fullTitle: String

  init(data: JSON) {
    self.data = data["value"].stringValue
    self.dayTitle = data["day"].stringValue
    self.description = data["label"].stringValue
    self.fullTitle = data["title"].stringValue
  }

  class func initArrayFrom(data: JSON) -> [ReservationSchedule] {
    var schedule: [ReservationSchedule] = []
    for day in data.arrayValue {
        schedule.append(ReservationSchedule.init(data: day)) //here is leak
    }
    return schedule
  }
}

【问题讨论】:

    标签: swift xcode memory-leaks alamofire instruments


    【解决方案1】:

    你是否尝试过设置 URLCache 时间来请求,这将删除请求的缓存并释放内存

    【讨论】:

      猜你喜欢
      • 2011-06-28
      • 2011-06-07
      • 2011-10-10
      • 2012-12-16
      • 2010-10-09
      • 2010-12-01
      • 2011-11-08
      • 1970-01-01
      相关资源
      最近更新 更多