代表级别从未发布过

时间:2018-03-13 13:25:37

标签: swift memory-management memory-leaks retain-cycle

我遇到了问题,如果我将委托类作为委托传递给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")

如果我将nil代替self作为代理,Downloader将被取消初始化;但显然这不是一个解决方案^^

1 个答案:

答案 0 :(得分:2)

请阅读URLSession init(configuration:delegate:delegateQueue:)的文档和delegate参数的说明:

  

重要

     

会话对象保留对委托的强引用,直到您的应用退出或显式使会话无效为止。如果您没有通过调用invalidateAndCancel()或finishTasksAndInvalidate()方法使会话无效,那么您的应用程序会泄漏内存直到它退出。

self.session完成会话时,您需要在Downloader上调用这两种方法之一。