保留URLSessionTask的引用是否有必要?
I've looked through multiple examples involving URLSession and URLSessionTask, including code snippets and downloadable sample projects. Most focus on common scenarios of using URLSessionDataTask to request data from REST services, and the code structure of most classes looks like this:
var defaultSession: URLSession var dataTask: URLSessionDataTask? override init() { let configuration = URLSessionConfiguration.default self.defaultSession = URLSession(configuration: configuration, delegate: nil, delegateQueue: self.operationQueue) super.init() } func callService(with searchUrl: URL, completion: @escaping (Data?, URLResponse?, Error?) -> Void) { dataTask = defaultSession.dataTask(with: searchUrl, completionHandler: completion) dataTask?.resume() }
I notice that the code usually keeps a reference to
dataTask, but this reference is only used within the above method. I want to understand why we need to retain a URLSessionTask reference?
Great question! Even though the reference only gets assigned and resumed in that one method, holding onto the URLSessionTask instance serves several critical, real-world purposes:
- Enable on-demand task cancellation: If the user decides to abort the request mid-flight (like navigating away from the screen, changing a search query, or dismissing a loading UI), you need that reference to call
dataTask?.cancel(). Without it, you have no way to stop the task, which will keep running until it finishes or fails—wasting bandwidth and system resources unnecessarily. - Prevent premature ARC deallocation: While
URLSessiondoes hold its own reference to active tasks, there are edge cases where Automatic Reference Counting (ARC) might deallocate your task instance before it completes if you don't have a strong external reference. Retaining it ensures the task can run to completion as intended. - Support state management & control: If you ever need to check the task's status (using
dataTask?.stateto see if it's running, suspended, or completed), or pause/resume the task later withsuspend()/resume(), you'll need that reference to interact with the task directly. - Avoid duplicate requests: You can add a quick check at the start of
callServiceto see ifdataTask?.state == .running—if it is, you can skip launching a new request. This prevents redundant network calls, which is especially useful if the user triggers the action multiple times quickly.
Many basic examples only show the minimal code to get a request working, but they keep the reference in place to accommodate these common production-ready features you'd add later.
内容的提问来源于stack exchange,提问作者AppsDev

