0

I have the problem, that my delegate-class is never reinitialised if I pass it as delegate to NSURLSession:

// Playground-compatible
import Foundation

class Downloader: NSObject, URLSessionDataDelegate {
    private var session: URLSession! = nil
    private var dataTask: URLSessionDataTask! = nil

    init(url: URL) {
        super.init()
        let request = URLRequest(url: url, cachePolicy: .reloadIgnoringCacheData, timeoutInterval: 60)
        self.session = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: OperationQueue.main)
        self.dataTask = session.dataTask(with: request)
    }

    deinit {
        print("Downloader released")
    }

    func dummy() -> String {
        self.dataTask = nil // I've also tried it without this
        self.session = nil  // I've also tried it without this
        return "Dummy ‍"
    }
}
func test() {
    let downloader = Downloader(url: URL(fileURLWithPath: "/"))
    print(downloader.dummy())
}

test()
print("After test")

If I pass nil instead of self as delegate, Downloader is deinitialized; but obviously this is not a solution^^

K. Biermann
  • 1,295
  • 10
  • 22

1 Answers1

2

Please read the documentation for URLSession init(configuration:delegate:delegateQueue:) and the description for the delegate parameter:

Important

The session object keeps a strong reference to the delegate until your app exits or explicitly invalidates the session. If you do not invalidate the session by calling the invalidateAndCancel() or finishTasksAndInvalidate() method, your app leaks memory until it exits.

You need to call one of those two methods on self.session when your Downloader is finished with the session.

Community
  • 1
  • 1
rmaddy
  • 314,917
  • 42
  • 532
  • 579