大佬教程收集整理的这篇文章主要介绍了ios – 如何解决Swift 4中的内存循环URLSession.downloadTask?,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我非常小心地将任何强大的指针传递给viewcontroller.而且我可以将视图控制器解散掉并且回到演示控制器而没有任何问题.但是,即使调用了viewcontroller的deinit,也不会释放由viewcontroller创建的Web()对象实例.
我究竟做错了什么?
BTW:启动文件下载,报告进度并报告文件位置.但是,一旦文件下载完毕,该对象永远不会被释放.
viewController.swift
@IBACtion func buttonTapped(_ sender: UIButton) { //first create an instance of Web class (download Helper) let web = Web(url: "https://www.google.com.sa/images/branding/googlelogo/2x/googlelogo_color_120x44dp.png") // all call BACk closures have no reference to self web.downloadFile( finishedHandler: {fileLOCATIOn in print("file stored to \(fileLOCATIOn)")},progressHandler: {Bytes,@R_21_10586@l in print("written \(bytes) out of \(@R_21_10586@l)")},errorHandler: {msg in print("error: \(msg)")} ) }
我已经将Web()定义为NSObject,它符合URLSessionDownloadDelegate以利用委托事件方法(didFinishDownload / didWriteBytes等).
Web.swift
import UIKit class Web : NSObject { var urlToDownload : String? // the following variables are references to closures passed to the object. var progressCallBACk : ((_ bytesWritten:Int64,_ @R_21_10586@lExpectedBytes: Int64)->())? var finishedCallBACk : ((_ fileLOCATIOn: String)->())? static var instanceCount = 0 // keep track of number of instances created init(url: String) { Web.instanceCount += 1 urlToDownload = url print(" new instance of Web created. @R_21_10586@l : \(Web.instanceCount)") } deinit { Web.instanceCount -= 1 print("Web instance deallocated. Remaining: \(Web.instanceCount)") } }
extension Web : URLSessionDownloadDelegate { func downloadFile( finishedHandler: @escaping (_ fileLOCATIOn:string)->(),progressHandler: @escaping (_ bytesWritten:Int64,_ @R_21_10586@lBytes: Int64)->(),errorHandler: @escaping (_ errorMsg:string)->()) { // we need to capture the closure because,these will // be called once the delegate methods are triggered self.progressCallBACk = progressHandler self.finishedCallBACk = finishedHandler if let url = URL(String: self.urlToDownload!) { let session = URLSession( configuration: .default,delegate: self,delegateQueue: nil) let task = session.downloadTask(with: url) task.resume() } } // MARK :- Delegate methods func urlSession(_ session: URLSession,downloadTask: URLSessionDownloadTask,didFinishDownloadingTo LOCATIOn: URL) { // call the closure if it still exists self.finishedCallBACk?(LOCATIOn.absoluteString) } func urlSession(_ session: URLSession,didWriteData bytesWritten: Int64,@R_21_10586@lBytesWritten: Int64,@R_21_10586@lBytesExpectedToWrite: Int64) { // report progress by calling captured closure,if exists self.progressCallBACk?(@R_21_10586@lBytesWritten,@R_21_10586@lBytesExpectedToWritE) } }
if let url = URL(String: self.urlToDownload!) { let session = URLSession( configuration: .default,delegateQueue: nil) let task = session.downloadTask(with: url) task.resume() }
实际上有一个与实例化URLSession相关的问题没有摆脱它;因此,你必须做一个 – 手动处理来解决它,调用finishTasksAndInvalidate()
将适合这样的问题:
if let url = URL(String: self.urlToDownload!) { let session = URLSession( configuration: .default,delegateQueue: nil) let task = session.downloadTask(with: url) task.resume() // here we go: session.finishTasksAndInvalidate() }
为了确保它按预期工作,我建议在委托方法和Web类中的deinit中添加断点,你应该看到它按预期工作(委托方法可以工作,然后调用deinit).
此外:
如果您想了解有关如何使用Memory Graph Debugger的更多信息,可以查看:How to debug memory leaks when Leaks instrument does not show them?
以上是大佬教程为你收集整理的ios – 如何解决Swift 4中的内存循环URLSession.downloadTask?全部内容,希望文章能够帮你解决ios – 如何解决Swift 4中的内存循环URLSession.downloadTask?所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。