Ios 更新FRC后TableViewController未刷新

Ios 更新FRC后TableViewController未刷新,ios,swift,nsfetchedresultscontroller,Ios,Swift,Nsfetchedresultscontroller,在NSFetchedResultsController FRC中选择一行时,我的应用程序允许通过切换到详细视图控制器来更改详细信息。保存更改后,将返回已编辑的行并将其插入FRC .update代码在以下开关中触发: 单元类定义为: class PlayerTableViewCell: UITableViewCell { //MARK: Properties @IBOutlet weak var playerFullName: UILabel! @IBOutlet wea

在NSFetchedResultsController FRC中选择一行时,我的应用程序允许通过切换到详细视图控制器来更改详细信息。保存更改后,将返回已编辑的行并将其插入FRC

.update代码在以下开关中触发:

单元类定义为:

class PlayerTableViewCell: UITableViewCell {

    //MARK: Properties
    @IBOutlet weak var playerFullName: UILabel!
    @IBOutlet weak var playerPhoto: UIImageView!
    @IBOutlet weak var exactHandicapLabel: UILabel!
    @IBOutlet weak var strokesReceivedLabel: UILabel!
    @IBOutlet weak var numExactHandicap: UILabel!
    @IBOutlet weak var numStrokesReceived: UILabel!

   override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }
}

-编辑1-

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    // Table view cells are reused and should be dequeued using a cell identifier
    let cell = tableView.dequeueReusableCell(withIdentifier: "PlayerTableViewCell", for: indexPath)

    configureCell(cell: cell, indexPath: indexPath as NSIndexPath)

    return cell
}
我的行为在很多方面都是出乎意料的

处理.update代码后,屏幕数据不会更新,保留FRC中的预编辑值

只有在表中选择同一行时,该行才会刷新。也就是说,在再次启动编辑的行之前,它显示旧值,但在我再次选择该行时会更改为新值

当我选择除第0行以外的任何行时,它第一次将单元格中的所有值设置为故事板中显示的默认值。但是,在任何情况下,行0都不会在序列之前更改

欢迎任何意见

-编辑3【2017年4月20日】-

我一直在琢磨这个问题有一段时间了。核心问题仍然存在-屏幕数据在处理.update代码后不会刷新,保留FRC中的预编辑值

关键代码段现在如下所示:

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
    switch type {
    case .update:
        golferView.reloadRows(at: [indexPath!], with: .automatic)
    case .insert:
        golferView.insertRows(at: [newIndexPath!], with: .automatic)
    case .delete:
        golferView.deleteRows(at: [indexPath!], with: .automatic)
    case .move:
        golferView.moveRow(at: indexPath! as IndexPath, to: newIndexPath! as IndexPath)
    }
}

func configureCell(cell: UITableViewCell, indexPath: NSIndexPath) {
    var handicap: Float
    var player: Golfer

    let cellIdentifier = "PlayerTableViewCell"

    guard let cell = golferView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath as IndexPath) as? PlayerTableViewCell else {
        fatalError("The dequeued cell is not an instance of PlayerTableViewCell")
    }

    // Populate cell from the NSManagedObject instance
    player = fetchedResultsController.object(at: indexPath as IndexPath)

    let firstName = player.value(forKey: "firstName") as! String?
    let lastName = player.value(forKey: "lastName") as! String?
    let fullName = firstName! + " " + lastName!
    handicap = player.value(forKey: "exactHandicap") as! Float

    cell.playerFullName?.text = fullName

    cell.playerPhoto.image = UIImage(data: player.value(forKey: "photo") as! Data)

    cell.numExactHandicap.text = "\(Int(handicap))"
    cell.numStrokesReceived.text = "\(handicap.cleanValue)"

    print("Object for configuration: \(player). And cell values are = \(String(describing: cell.playerFullName?.text)), \(String(describing: cell.numExactHandicap.text)), \(String(describing: cell.numStrokesReceived.text))")
}

我已经验证了控制器方法是否正确触发,以及.update开关是否触发了重载行。这进而触发configureCell,其中FRC返回的行的内容正确,插入单元格的值与FRC返回的值匹配。它只是不会刷新UI。

在调查内存使用问题时,我偶然发现对dequeueReusableCell的重复调用,修复后,解决了我一直遇到的问题

在我的帖子中,在configureCell中调用了dequeueReusableCell。在重写func tableView\utableview:UITableView,cellforrow的indexPath:indexPath->UITableViewCell调用中,在调用configureCell之前也会立即调用它


我现在又回到正轨上了

您确定正在调用您的更新代码吗?此外,您不需要同时调用configureCell和reloadRows。您所说的编辑行返回并插入FRC是什么意思。这是正在创建的新行,不是更新吗?嗨,Dave。顺序:1。是,正在调用.update代码。当我在那里设置断点时,它会停止并允许我单步执行。2.如果我注释掉对reloadRows的调用,那么行为就会改变。现在,它不再显示原始的、预编辑的行内容,而是将行的内容重置为默认的情节提要值。调用reloadRows会用过期的行填充表,而不是我想要的更新值。3.我的意思是,我希望编辑的详细信息反映为FRC中原始行的更新。我的意思是您应该删除configureCell方法调用,因为这将通过重新加载该行自动调用。如果检查该对象,其值是否正确?你能分享你的tableView吗?嗨,戴夫。你的观点是:1。我删除了ConfigureCell调用,正如您所建议的,它是多余的。2.是的,anObject'的值包含我在segue之前设置的值,因此切换正常。3.我已经在原始问题中包含了tableView_u:cellForRowAt:`方法的代码作为编辑。再次感谢。
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    // Table view cells are reused and should be dequeued using a cell identifier
    let cell = tableView.dequeueReusableCell(withIdentifier: "PlayerTableViewCell", for: indexPath)

    configureCell(cell: cell, indexPath: indexPath as NSIndexPath)

    return cell
}
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
    switch type {
    case .update:
        golferView.reloadRows(at: [indexPath!], with: .automatic)
    case .insert:
        golferView.insertRows(at: [newIndexPath!], with: .automatic)
    case .delete:
        golferView.deleteRows(at: [indexPath!], with: .automatic)
    case .move:
        golferView.moveRow(at: indexPath! as IndexPath, to: newIndexPath! as IndexPath)
    }
}

func configureCell(cell: UITableViewCell, indexPath: NSIndexPath) {
    var handicap: Float
    var player: Golfer

    let cellIdentifier = "PlayerTableViewCell"

    guard let cell = golferView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath as IndexPath) as? PlayerTableViewCell else {
        fatalError("The dequeued cell is not an instance of PlayerTableViewCell")
    }

    // Populate cell from the NSManagedObject instance
    player = fetchedResultsController.object(at: indexPath as IndexPath)

    let firstName = player.value(forKey: "firstName") as! String?
    let lastName = player.value(forKey: "lastName") as! String?
    let fullName = firstName! + " " + lastName!
    handicap = player.value(forKey: "exactHandicap") as! Float

    cell.playerFullName?.text = fullName

    cell.playerPhoto.image = UIImage(data: player.value(forKey: "photo") as! Data)

    cell.numExactHandicap.text = "\(Int(handicap))"
    cell.numStrokesReceived.text = "\(handicap.cleanValue)"

    print("Object for configuration: \(player). And cell values are = \(String(describing: cell.playerFullName?.text)), \(String(describing: cell.numExactHandicap.text)), \(String(describing: cell.numStrokesReceived.text))")
}