修复UITableVIew滞后

时间:2017-05-04 08:04:26

标签: swift uitableview swift3

我正在关注this教程如何避免UITableView的滞后,但人口数据效果不佳。有时显示错误的数据并且不再更改,或者显示错误然后切换到正确的数据。

我怎么能解决这个问题?

这是教程中需要的课程

class SerialOperationQueue: OperationQueue
{
    override init()
    {
        super.init()
        maxConcurrentOperationCount = 1
    }
}

然后在VehicleCell课程中我有

let queue = SerialOperationQueue()

在模型方法中,从教程中可以看出:

模板:

func setSomething(vehicle: VehicleModel) -> String {
        Thread.sleep(forTimeInterval: 0.01)
        return "some string from model"
    }

UITableViewDataSource我有

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        return vehiclesTableView.dequeueReusableCell(withIdentifier: "vehicleCell", for: indexPath) as! VehiclesCell   
    }

willDisplay

 func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        if let cell = cell as? VehiclesCell {
            configureCell(cell: cell, indexPath: indexPath)
        }

cell.alpha = 0
        cell.layer.transform = CATransform3DMakeScale(0.1, 0.1, 1)

        cell.layoutIfNeeded()
        cell.layer.removeAllAnimations()
        UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseOut, animations: {
            cell.alpha = 1
            cell.layer.transform = CATransform3DMakeScale(1, 1, 1)
            cell.layoutIfNeeded()
        })
    }

private func configureCell(cell: VehiclesCell, indexPath: IndexPath) {

        cell.queue.cancelAllOperations()
        let operation: BlockOperation = BlockOperation()

        operation.addExecutionBlock {
            let vehicles = self.checkForVehicles(inSection: indexPath.section)
            let vehicle = vehicles[indexPath.row]
            let vehicleName = self.setVehicleName(vehicle: vehicle)
            let driverName = self.setDriverName(vehicle: vehicle)
            let topColor = self.setTopLineColor(vehicle: vehicle, colorView: cell.topColorView)
            let vehicleImage = self.setVehicleImage(vehicle: vehicle)
            let address = self.setAddress(vehicle: vehicle)
            let engineStatus = self.setEngineStatus(vehicle: vehicle)
            let hosStatus = self.setHosStatus(vehicle: vehicle)
            let speed = self.setSpeed(vehicle: vehicle)
            DispatchQueue.main.async {

                if operation.isCancelled { return }

                cell.vehicleNameLabel.text = vehicleName
                cell.driverNameLabel.text = driverName
                cell.topColorView = topColor
                cell.vehicleImageView.image = vehicleImage
                cell.localizationLabelView.text = address
                cell.engineLabel.text = engineStatus
                cell.hosStatusLabel.text = hosStatus
                cell.speedValueLabel.text = speed
            }
        }

        cell.queue.addOperation(operation)
    }

有人能解释我这种行为吗?为什么单元格填充了错误的数据,然后当它们变得正确时,它们会切换。他们可能会保持这样状态而不会转换为良好的数据吗?

解决这个问题的最佳选择是什么?

提前致谢!

1 个答案:

答案 0 :(得分:0)

问题是您没有覆盖VehicleCell中的prepareForReuse function

由于单元格在UITableView中被重用以获得更平滑的性能,因此它会重复使用tableView中的单元格,而不是每次需要新单元格时都创建新实例。

执行此操作时:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        return vehiclesTableView.dequeueReusableCell(withIdentifier: "vehicleCell", for: indexPath) as! VehiclesCell   
}

而不是创建新的单元格,您可以使用标识符对可重复使用的单元格进行出列。

因此,重要的是,您覆盖perpareForReuse函数。查看您的VehicleCell界面,它应该如下所示:

override func prepareForReuse() {
    super.prepareForReuse()
    self.vehicleNameLabel.text = nil
    self.driverNameLabel.text = nil
    self.topColorView = nil
    self.vehicleImageView.image = nil
    self.localizationLabelView.text = nil
    self.engineLabel.text = nil
    self.hosStatusLabel.text = nil
    self.speedValueLabel.text = nil
}

willDisplayCell中的所有代码都是不需要的代码,什么不起作用,根本就没有意义。

修改 我喜欢configureCell方法,但不喜欢使用队列。所以我建议你做以下事情:

  1. 删除willDisplay功能。
  2. configureCell
  3. 中删除所有此BlockOperation和队列相关代码
  4. configureCell致电cellForRowAt,并在设置完成后返回
  5. ```

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell: VehiclesCell = vehiclesTableView.dequeueReusableCell(withIdentifier: "vehicleCell", for: indexPath) as! VehiclesCell
        self.configureCell(cell: cell, indexPath: indexPath)
        return cell
    }    
    
    private func configureCell(cell: VehiclesCell, indexPath: IndexPath) {
    
        let vehicles = self.checkForVehicles(inSection: indexPath.section)
        let vehicle = vehicles[indexPath.row]
        let vehicleName = self.setVehicleName(vehicle: vehicle)
        let driverName = self.setDriverName(vehicle: vehicle)
        let topColor = self.setTopLineColor(vehicle: vehicle, colorView: cell.topColorView)
        let vehicleImage = self.setVehicleImage(vehicle: vehicle)
        let address = self.setAddress(vehicle: vehicle)
        let engineStatus = self.setEngineStatus(vehicle: vehicle)
        let hosStatus = self.setHosStatus(vehicle: vehicle)
        let speed = self.setSpeed(vehicle: vehicle)
    
        cell.vehicleNameLabel.text = vehicleName
        cell.driverNameLabel.text = driverName
        cell.topColorView = topColor
        cell.vehicleImageView.image = vehicleImage
        cell.localizationLabelView.text = address
        cell.engineLabel.text = engineStatus
        cell.hosStatusLabel.text = hosStatus
        cell.speedValueLabel.text = speed
    }
    

    ```