iOS   发布时间:2022-03-30  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了ios – 如何解决Swift 4中的内存循环URLSession.downloadTask?大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
@H_874_1@
@L_262_0@一个基本的viewController,只有一个按钮,当点击时,调用一个方法开始从给定的有效URL下载图像.

我非常小心地将任何强大的指针传递给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)
    }
}

解决方法

在我跟踪了这​​个问题后(使用Memory Graph Debugger),我在这代码(Web类 – 下载文件方法)中找出问题的原因:

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,请注明来意。