我有一个应用程序(部分)显示用户的Wi-Fi连接的当前下载速度。它通过打开URLSession
并下载中等大小(~10MB)文件并测量所花费的时间来实现。
这是URLSession函数:
func testSpeed() {
Globals.shared.dlStartTime = Date()
Globals.shared.DownComplete = false
if Globals.shared.currentSSID == "" {
Globals.shared.bandwidth = 0
Globals.shared.DownComplete = true
} else {
let url = URL(string: [HIDDEN])
let session = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: nil)
let task = session.downloadTask(with: url!)
task.resume()
}
}
public func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
Globals.shared.dlFileSize = (Double(totalBytesExpectedToWrite) * 8) / 1000
let progress = (Double(totalBytesWritten) / Double(totalBytesExpectedToWrite)) * 100.0
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "ProcessUpdating"), object: nil, userInfo: ["progress" : progress])
}
public func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
let elapsed = Double( Date().timeIntervalSince(Globals.shared.dlStartTime))
Globals.shared.bandwidth = Int(Globals.shared.dlFileSize / elapsed)
Globals.shared.DownComplete = true
Globals.shared.dataUse! += (Globals.shared.dlFileSize! / 8000)
session.invalidateAndCancel()
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "ProcessFinished"), object: nil, userInfo: nil)
}
正如您可以通过委托函数所知,这一切都存在于视图控制器的单独类中,以及其他一些小型网络功能,如获取IP和SSID。代表发布视图控制器观察到的通知。
我的ViewController有一个NSTimer,它每5秒回调一次这个URLSession以重新测试速度(但只有在前一个完成时才运行它)。这是代码:
reloadTimer = Timer.scheduledTimer(timeInterval: 5.0, target: self, selector: #selector(rescanNetwork), userInfo: nil, repeats: true)
调用此功能:
func backgroundRescan() {
if Globals.shared.DownComplete {
Networking().testSpeed()
}
}
再次运行URL会话,当然要检查以确保先前已完成。
出于某种原因,我在测试中会大量增加内存使用量,直到应用程序达到2GB的内存使用量并被控制台输出Message from debugger: Terminated due to memory issue
终止。这一切都发生在运行应用程序的两分钟内。
我甚至将session.invalidateAndCancel()
添加到完成委托中,以绝望的方式清除内存。但它没有用。我错过了什么吗?
答案 0 :(得分:2)
正如Rob所说,将URLSessionConfiguration.default作为类中的变量并使用它。 我遇到了同样的问题,最后通过使用包含所有通信方法的singelton类并将URLSessionConfiguration.default设置为成员变量来解决它。我的所有内存泄漏都得到了解决。