排队的任务以及完成之前可能的卸载

时间:2018-08-21 09:21:08

标签: swift asynchronous queue task dispatch-async

我正在制作一个带有后台Web数据库的软件。我正在将数据从Web加载到表视图和集合视图。有时这些是较大的照片。所有这些数据加载都异步运行,因此,例如,加载了表,但没有照片,并且照片被加载到单独的队列中。我不确定如果在下载照片之前关闭正在加载照片的视图会发生什么情况。下面是加载数据的代码作为示例。

        DispatchWork = DispatchWorkItem(block: {
        let thisData = try? Data(contentsOf: thisURL!)
        DispatchQueue.main.async {
            self.jSonData = try! JSONSerialization.jsonObject(with: thisData!, options: []) as! [[String: String]]
            self.counter = self.jSonData.count
            self.tableView.reloadData()
        }
    })
    DispatchQueue.global(qos: .userInitiated).async(execute: DispatchWork!)

这是可行的,但是到目前为止,如果在加载所有内容之前关闭视图,我将无法进行测试。我已经尝试了deinit部分中的DispatchWork.cancel(),但根本没有调用它。

恐怕如果视图尚未显示,正在运行的任务可能会导致正在运行的任务尝试使用下载的数据更新视图,并且程序将因此崩溃。

这有一个好的做法吗?

1 个答案:

答案 0 :(得分:0)

按照您当前的代码状态,它只会继续执行预期的工作。异步闭包不使用对自身的弱引用,因此如果我没记错的话,它们可以保留强引用,直到异步任务完成。因此,在完成关闭VC时正在运行的所有异步任务的操作完成后,应该重新分配View控制器,从而图像下载和内容将继续正常运行并在完成后更新图像视图。

为了更好地进行内存管理,您应该在视图控制器的异步闭包中使用[weak self],以便在关闭视图控制器时,没有强引用将其保留在内存中。很可能所有开始的下载都将继续,直到完成或出现错误。但是,它们不会导致视图控制器停留在内存中并在收到响应时运行闭包。