ios - 为什么以这种方式更新 UITableView 单元格是错误的?

标签 ios swift uitableview

我正在制作一个下载管理器,由于“可重用单元”的原因,我一直在努力更新单元......

我在滚动后更新单元格时遇到问题,但我找到了一个无法正常工作的解决方法,这种方式会导致应用程序在单元格变得不可见后崩溃,我不知道为什么我希望你们可以解释一下,如果您知道如何解决它,请告诉我。

我这样添加下载任务

func addDownloadTask(URL: NSURL) {

    let sessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration()
    let mainQueue = NSOperationQueue.mainQueue()
    let session = NSURLSession(configuration: sessionConfiguration, delegate: self, delegateQueue: mainQueue).downloadTaskWithURL(URL)

    let newDownload = RCHDownloadAddictModelClass(fileURL: URL)

    newDownload.downloadTask = session

    downloadingArray.append(newDownload)

    newDownload.downloadIndex = downloadingArray.indexOf(downloadingArray.last!)

    self.tableView.reloadData()

    session.resume()

}

NSURLSessionDownloadTask开始下载时调用此方法

func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {

    for (index, downloadModel) in downloadingArray.enumerate() {
        if downloadTask.isEqual(downloadModel.downloadTask) {
            dispatch_async(dispatch_get_main_queue(), {

                let indexPath = NSIndexPath(forRow: index, inSection: 0)
                /* xCode stops here when the app crashes */ let cell = self.tableView.cellForRowAtIndexPath(indexPath) as! RCHDownloadAddictTableViewCell 
                let countOfBytesWritten: Double!
                if totalBytesExpectedToWrite < 0 {

                    countOfBytesWritten = 0

                } else {

                    countOfBytesWritten  = Double(totalBytesWritten) / Double(totalBytesExpectedToWrite)

                }

                downloadModel.fileName = downloadTask.response?.suggestedFilename
                downloadModel.downloadIndex = downloadingArray.indexOf(downloadModel)
                downloadModel.downloadSize = Double(totalBytesExpectedToWrite)
                downloadModel.downloadProgress = Float(countOfBytesWritten)
                downloadModel.downloadTaskIdentifier = downloadTask.taskIdentifier
                downloadModel.didFinishDownload = false

                self.updateCell(cell, forRowAt: indexPath)

            })
        }
    }


}

这就是单元格更新的方式:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("downloadCell", forIndexPath: indexPath) as! RCHDownloadAddictTableViewCell

    updateCell(cell, forRowAt: indexPath)

    return cell
}



func updateCell(cell: RCHDownloadAddictTableViewCell, forRowAt indexPath: NSIndexPath) {

    let arrayInfo = downloadingArray[indexPath.row]

    cell.cellProgressView.setProgress((arrayInfo.downloadProgress)!, animated: true)
    cell.cellFileName.text = arrayInfo.fileName
    cell.cellDownloadSpeed.text = String(format: "%.1fMB", (arrayInfo.downloadSize / 1000000))
    cell.cellBlock = {

        switch arrayInfo.downloadTask.state {
        case .Running:
            arrayInfo.downloadTask.suspend()
            cell.cellButton.setImage(UIImage(named: "resume.png"), forState: UIControlState.Normal)
        case .Suspended:
            arrayInfo.downloadTask.resume()
            cell.cellButton.setImage(UIImage(named: "pause.png"), forState: UIControlState.Normal)
        default:
            arrayInfo.downloadTask.suspend()
            cell.cellButton.setImage(UIImage(named: "resume.png"), forState: UIControlState.Normal)
        }

    }

    if (arrayInfo.didFinishDownload == true) {
        cell.cellButton.hidden = true
        cell.cellFinishIndicator.text = "Finished."
        cell.cellProgressView.hidden = true
        cell.cellFinishIndicator.hidden = false
    } else {
        cell.cellButton.hidden = false
        cell.cellProgressView.hidden = false
        cell.cellFinishIndicator.hidden = true
    }

}

最佳答案

你可以在苹果文档中看到它:

public func cellForRowAtIndexPath(indexPath: NSIndexPath) -> UITableViewCell? 
// returns nil if cell is not visible or index path is out of range

//cell will be nil when this row is not visible
let cell = self.tableView.cellForRowAtIndexPath(indexPath) as! RCHDownloadAddictTableViewCell 

然后你调用self.updateCell(cell, forRowAt: indexPath)它会崩溃

关于ios - 为什么以这种方式更新 UITableView 单元格是错误的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37411532/

相关文章:

ios - 从图像数组中快速删除图像

ios - 将 iOS 应用程序重新连接到配对的蓝牙设备?

ios - 如何通过 UIActivityViewController 打印 UIWebView?

swift - 如何使用自定义对象填充 TableView ?

ios - 在以编程方式创建的 tableView 中重新加载数据

ios - 可以将 "self"与 NSSortDescriptor 一起使用以按对象本身而不是对象的属性进行排序吗? (核心数据/NSFetchedResultsController)

ios - Ionic 4 - 应用内购买产品信息在购买前无法显示

ios - updateChildValues 似乎不仅更新值

ios - 在 View 大小更改时更改 UIView 阴影大小会产生奇怪的效果

iphone - 如何从表格 View 中完全隐藏某个单元格?