Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should NSURLSession be a weak property

I'm investigating a memory leak and from using the Malloc option, it looks like a class that we have has this:

enter image description here

The class, SessionManager, has

@property(nonatomic, strong) NSURLSession *urlSession;

- (instancetype)initWithConfiguration(NSURLSessionConfiguration)configuration {
    if (self = [super init]) {
    _urlSession = [NSURLSession sessionWithConfiguration:configuration delgate: self delegateQueue:_sessionQueue];


    }

    return self;
}

I'm not sure how to read this, except if I could guess, it'd be the NSURLSession holds onto the SessionManager as well as the SessionManager having a strong reference to NSURLSession. Should the property for NSURLSession be weak or unowned?

Secondly, if so, what would the reason be for this?

like image 936
Crystal Avatar asked Dec 26 '17 21:12

Crystal


2 Answers

Your assumption is right. From documentation:

Discussion

This delegate object is responsible for handling authentication challenges, for making caching decisions, and for handling other session-related events. The session object keeps a strong reference to this delegate until your app exits or explicitly invalidates the session. If you do not invalidate the session, your app leaks memory until it exits.

Which basically means exactly what you wrote. You have double-sided strong reference cycle. And as you said you could break it by setting urlSession to be weak reference. However this may (but not necessary) cause undesirable side effects like immediately losing your urlSession after creating it since no object captures the strong reference to it.

I'd advice

  • making sure that exactly this part of code really makes some major memory leaks (since right now it looks like a simple kind of singleton that should not take too much memory)
  • if it really makes memory leak - reconsider your architecture so that you could invalidate sessions.

P.S.

If your primary goal is to investigate memory leak it would be helpful to take a look at the left panel of Xcode while debugging memory graph to analyze object counters and Xcode's hints (exclamation marks in violet rectangles).

like image 71
Fyodor Volchyok Avatar answered Nov 03 '22 09:11

Fyodor Volchyok


As URLSession documentation says:

The session object keeps a strong reference to the delegate until your app exits or explicitly invalidates the session.

Because your session manager has a strong reference to the session and the session has a strong reference to its delegate, you have a strong reference cycle, not unresolved until the app terminates or the session is invalidated.

If you want to avoid this, I would not use a weak reference to the URLSession. Instead, I'd be inclined to move the URLSession delegate methods to a stand-alone delegate object rather than keeping them in your SessionManager object. This will avoid the strong reference cycle. It's potentially a cleaner design, too, in keeping with the "single responsibility principle."

But it should be recognized that this doesn't really change the fundamental memory characteristics of the app. The app presumably maintains reference to session manager, which maintains reference to the session, which maintains strong reference to the delegate object. The memory associated with the delegate object will not be released until the session is invalidated. But it avoids the strong reference cycle which may otherwise be cluttering your "debug memory graph" analysis.

like image 2
Rob Avatar answered Nov 03 '22 09:11

Rob