在CustomTableViewCell.swift中调用prepareForReuse()时,UITableViewCells在从UITableView(Swift 3)删除几次后变得无响应

Tre*_*v14 0 uitableview ios swift firebase-realtime-database

我有一个应用程序从Firebase中提取对象,然后将它们显示在表格中.我注意到如果我删除了5个条目(这是关于当我到达被删除的重用单元格时),我不能再删除(红色删除按钮没有响应)甚至不能选择单元格.当我override func prepareForReuse()在TableViewCell.swift控制器中注释掉时,此行为停止.为什么???

应用程序的其余部分正常运行,而单元格只是没有响应.奇怪的是,如果我用一根手指放在一个牢房上,用另一根手指敲击牢房,我就可以选择这个牢房.然后,如果我用手指按住单元格并点击删除按钮,该单元格将再次开始正常运行.这里发生了什么?这是表格和单元格的代码:

在CustomTableViewCell.swift >>中

override func prepareForReuse() {
    // CELLS STILL FREEZE EVEN WHEN THE FOLLOWING LINE IS COMMENTED OUT?!?!
    cellImage.image = nil
}
Run Code Online (Sandbox Code Playgroud)

在ViewController.swift >>中

override func viewDidLoad() {
    super.viewDidLoad()

    loadUserThings()
}

func loadUserThings() {
    ref.child("xxx").child(user!.uid).child("yyy").queryOrdered(byChild: "aaa").observe(.value, with: { (snapshot) in
        // A CHANGE WAS DETECTED. RELOAD DATA.
        self.arr = []
        for tempThing in snapshot.children {
            let thing = Thing(snapshot: tempThing as! DataSnapshot)
            self.arr.append(thing)
        }
        self.tableView.reloadData()
    }) { (error) in
        print(error)
    }
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomTableViewCell
    let cellData = arr[indexPath.row]
    ...
    // SET TEXT VALUES OF LABELS IN THE CELL
    ...
    // Setting image to nil in CustomTableViewCell
    let imgRef = storageRef.child(cellData.imgPath)
    let activityIndicator = MDCActivityIndicator()
    // Set up activity indicator
    cell.cellImage.sd_setImage(with: imgRef, placeholderImage: nil, completion: { (image, error, cacheType, ref) in
        activityIndicator.stopAnimating()
        delay(time: 0.2, function: {
            UIView.animate(withDuration: 0.3, animations: {
                cell.cellImage.alpha = 1
            })
        })
    })
    if cell.cellImage.image == nil {
        cell.cellImage.alpha = 0
    }
    // Seems like sd_setImage doesn't always call completion block if the image is loaded quickly, so we need to stop the loader before a bunch of activity indicators build up
    delay(time: 0.2) {
        if cell.cellImage.image != nil {
            activityIndicator.stopAnimating()
            cell.cellImage.alpha = 1
        }
    }
    return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    // instantly deselect row to allow normal selection of other rows
    tableView.deselectRow(at: tableView.indexPathForSelectedRow!, animated: false)
    selectedObjectIndex = indexPath.row
    self.performSegue(withIdentifier: "customSegue", sender: self)
}

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {
        print("should delete")
        let row = indexPath.row
        let objectToDelete = userObjects[row]
        userObjects.remove(at: row)
        ref.child("users/\(user!.uid)/objects/\(objectToDelete.nickname!)").removeValue()
        tableView.deleteRows(at: [indexPath], with: .fade)
    }
}

func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
    if (self.tableView.isEditing) {
        return UITableViewCellEditingStyle.delete
    }
    return UITableViewCellEditingStyle.none
}
Run Code Online (Sandbox Code Playgroud)

gwi*_*yai 8

一些东西.出于性能原因,您应该仅用于prepareForReuse重置与单元格外观相关的属性而不是内容(如图像和文本).在cellForRowAtIndexPathtableView的委托中设置文本和图像等内容,并重置单元格,编辑和选择状态等单元格外观属性prepareForReuse.我不确定为什么当你注释掉那行并prepareForReuse留空时它会继续表现得很糟糕,因为只要你使用自定义表视图单元格,空白就prepareForReuse不会影响性能.我只能假设它与你没有调用超类实现有关prepareForReuse,这是Apple根据文档要求的:

    override func prepareForReuse() {
        // CELLS STILL FREEZE EVEN WHEN THE FOLLOWING LINE IS COMMENTED OUT?!?!
         super.prepareForReuse()
    }
Run Code Online (Sandbox Code Playgroud)

prepareForReuse方法仅用于对自定义单元格进行小规模清理.