NSURLSession memory leak

后端 未结 3 1127
南方客
南方客 2021-01-15 01:26

Even after invalidate a NSURLSession, running a profile using Instruments, some classes (probably privates) called TubeManager, HTTPConnectionCache and HTTPConnectionCacheDi

3条回答
  •  悲哀的现实
    2021-01-15 01:35

    Note that on iOS 9, Security framework allocates appx. 4k of SSL cache data and charges it to your app the first time you resume a task for a new NSURLSession object. Apple Technical Q&A QA1727 tells us this SSL cache persists for 10 minutes, no matter what, since it's private and entirely managed by the system (because security!).

    In your code example, you are creating a new NSURLSession object each time you make a request. But you are just using defaultSessionConfiguration and not specifying a delegate to which a strong reference might exist, then what you should instead do is just use the singleton [NSURLSession sharedSession] and use resetWithCompletionHandler to clear up non-security allocations. Or make a custom singleton if you want to customize the configuration.

    • (NSURLSession *)sharedSession Discussion

    For basic requests, the URL session class provides a shared singleton session object that gives you a reasonable default behavior. By using the shared session, you can fetch the contents of a URL to memory with just a few lines of code.

    Unlike the other session types, you do not create the shared session; you merely request it by calling [NSURLSession sharedSession]. As a result, you don’t provide a delegate or a configuration object. Therefore, with the shared session:

       - You cannot obtain data incrementally as it arrives from the server.
       - You cannot significantly customize the default connection behavior.
       - Your ability to perform authentication is limited.
       - You cannot perform background downloads or uploads while your app is    
         not running.
    

    The shared session uses the shared NSURLCache, NSHTTPCookieStorage, and NSURLCredentialStorage objects, uses a shared custom networking protocol list (configured with registerClass: and unregisterClass:), and is based on a default configuration.

    When working with a shared session, you should generally avoid customizing the cache, cookie storage, or credential storage (unless you are already doing so with NSURLConnection), because there’s a very good chance that you’ll eventually outgrow the capabilities of the default session, at which point you’ll have to rewrite all of those customizations in a manner that works with your custom URL sessions.

    In other words, if you’re doing anything with caches, cookies, authentication, or custom networking protocols, you should probably be using a default session instead of the default session.

    (From NSURLSession Class Reference... Italics mine ;P)

    If you are not using the sharedSession Apple-provided singleton, then you should at least take a cue from Apple and roll your own singleton with a session property. The point of a session is that it is intended to live longer than just one request. Despite their unclear documentation, the fact that Apple provides a singleton, and calls it a "session", indicates session objects were meant to live longer than just a single request.

    Yeah, you are supposed to invalidateAndCancel at some point, but not after every single request, and not even if each request is going to a different server entirely (which is almost never the case). You only need to invalidate and cancel if you are going to break your reference to a particular session; otherwise, you can just call flushWithCompletionHandler or resetWithCompletionHandler on the session to flush your session's heap allocations to VM, or reset to clear both heap and VM storage. (Also see my answer here.)

提交回复
热议问题