Alamofire 5.0.0 beta memory leaks on `validate()`

Created on 3 Mar 2019  路  8Comments  路  Source: Alamofire/Alamofire

What did you do?

Hi,
I've been identifying odd memory leaks in my project overnight, and I stumbled upon this issue #1551.
I'm using Alamofire 5 beta version, and the validate() method seems to create a memory retain cycle.
I am opening a new issue, since I'm using the new 5 beta.

I am making simple GET / POST requests with AF.request with validate method, chained.
A code stub related to this issue are attached below.

What did you expect to happen?

The memory leaks shouldn't happen with validate().

What happened instead?

Leaks occur when I make requests with validate().
This occurs about every other time I make consecutive requests with time gap of about a second.

Alamofire Environment

Alamofire version: 5.0.0-beta.2
Xcode version: 10.1 (10B61)
Swift version: 4.2
Platform(s) running Alamofire: iOS 12.1 (16B91)
macOS version running Xcode: Mojave 10.14.2(18C54)

Demo Project

I'm doing a closed source project, but the codes that are causing the issue are some what like the following:

import Alamofire

class Networking {

// some methods...

  @discardableResult
  static func getSomthing(argument1: Int,
                          argument2: Int,
                          argument3: Bool = false,
                          completion: @escaping (DataResponse<Data?>) -> Void) -> DataRequest  {
    return AF.request(Router.something(.get(argument1: argument1,
                                             argument2: argument2,
                                             argument3: argument3)))
             .validate()  // Without this line, the leaks are gone!
             .response { response in
      switch response.result {
      case .success:
        completion(response)

      case .failure(let error):
        print("[Networking] \(error.localizedDescription)")
      }
    }
  }

// some other methods...
}

Without the .validate() line, the leaks are gone.

  • The following is the screenshot of 'Debug Memory Graph' from Xcode:

2019-03-03 17 43 35

bug

All 8 comments

I can replicate this. It appears we have a reference cycle in our validator storage, despite the fact that we're capturing unowned self. I'll see if I can write some tests around this to help debug.

There appears to be some sort of capture issue with validate(contentType:), as it uses an @autoclosure and any reference to self in the passed closure, even if captured weak or unowned, will trigger the cycle. I've opened a thread on the Swift Forums about it, so we'll see if anyone has any ideas.

@jshier For non-escaping closures, we don鈥檛 have to worry about capturing the self using weak or unowned keywords. It matters only for escaping closures.

Right, but this is escaping, namely @escaping @autoclosure, due to being stored in array to run after a response is received. Any self capture, even weak or unowned, in that parameter is responsible for the retain cycles.

I believe I've found a fix: https://github.com/Alamofire/Alamofire/pull/2728/commits/7fbe89bd12c6cf8a89baefca06ffae9f0ce8cc90

I've committed it to the bug/2682-complete-on-invalidation branch, as part of #2728. @Zeta611, can you verify that?

@jshier Great! Commit 7fbe89b does seem to fix the issue.
When should I expect this commit to be merged to the beta?

I should be able to get it merged into master this week. If I have time I should be able to cut a new beta release. In the mean time you can use it from the branch.

Great! Since this is resolved, I鈥檒l close this issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

hengchengfei picture hengchengfei  路  3Comments

sarbogast picture sarbogast  路  3Comments

yamifr07 picture yamifr07  路  3Comments

Footjy picture Footjy  路  3Comments

filippovdev picture filippovdev  路  3Comments