2017-01-11 26 views
13

tôi đang cố gắng để làm sạch ứng dụng của tôi từ rò rỉ bộ nhớ và tôi có một vài vấn đề hiểu biết nàynhớ Alamofire rò rỉ Instruments

enter image description here

  • Tại sao Alamofire chức năng Request.serializeResponseJSON được gọi là 30 giây sau khi tôi đã ra mắt ứng dụng: Tôi không chạm vào bất cứ điều gì hoặc điều hướng bất cứ nơi nào, màn hình tĩnh.

  • Tại sao nó bị rò rỉ?

  • Tại sao mã của tôi bị rò rỉ?

Tôi nhận được rò rỉ tương tự khi màn hình đã được tải.

Những gì tôi đã cố gắng cho đến nay:

  • Autoreleasepool;

  • Gắn và khởi tạo mảng theo mọi cách có thể;

  • Thay đổi tất cả biến (lớp, func) thành tùy chọn/không phải là tùy chọn/yếu;

  • Lớp khởi tạo trong UIViewController;

  • Lớp khởi tạo trong chuỗi chính;

  • Tìm kiếm các sự cố này trên internet.

  • Tôi đã phát hiện ra, sử dụng công cụ bộ nhớ Xcode, rằng nó được kết nối bằng cách nào đó với _ContiguousArrayStorage, nhưng tôi không hiểu nó thực sự như thế nào và nó là gì. enter image description here

Tôi không có ý tưởng gì sai ở đây. Bất kỳ lời khuyên nào cũng sẽ được nhiều đánh giá cao.

Dưới đây là tất cả các mã liên quan: yêu cầu API chung My

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

yêu cầu màn hình của tôi

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

lớp của tôi (tôi biết loại khởi động là kinda sai, nhưng tôi đã thay đổi đến init(data: JSON) - không trợ giúp:

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 
} 

Array của những rò rỉ:

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

Trả lời

0

Bạn đã cố gắng thiết lập URLCache thời gian yêu cầu, trình này sẽ xóa bộ nhớ cache của yêu cầu và tự do là bộ nhớ