UITableView向ViewController传数据异常:消息显示滞后问题咨询
问题解决:UITableViewCell跳转后Message字段显示延迟的问题
我有一个遵循Decodable协议的数据结构,其中Name字段显示在UITableViewCell的标签上,Message字段不显示,但需要和Name一起传递到目标ViewController。现在点击Cell跳转后,显示的Message是上一个Cell的内容,关闭详情页再次点击该Cell时,才能显示正确的Message。相关代码如下:
struct Response: Decodable { let array: [Content] struct Content: Decodable { let Name: String let Message: String } } var responseDec: Response?
以下是didSelectRow和prepare方法的代码:
var username = "" var message = "" func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let res = self.responseDec?.array[indexPath.row] index = indexPath.row username = res?.Name ?? "N/A" message = res?.Message ?? "N/A" let cell = tableView.cellForRow(at: indexPath) as? Cell performSegue(withIdentifier: "goToVC", sender: cell) } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "goToVC" { let cell = sender as? Cell let vc = segue.destination as! ViewController vc.name = cell?.nameLabel.text ?? "N/A" vc.message = message } }
问题原因
你依赖全局变量message传递数据,而performSegue的执行时机与全局变量赋值的状态可能存在冲突,快速操作时容易出现旧值覆盖的情况;同时通过Cell获取Name的方式也没必要,直接从数据源取数据更可靠。
解决方法
方案一:直接传递选中的数据源对象
修改didSelectRowAt方法,把选中的Content对象作为sender传递:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { guard let selectedContent = self.responseDec?.array[indexPath.row] else { return } performSegue(withIdentifier: "goToVC", sender: selectedContent) }
修改prepare(for:sender:)方法,直接从sender中解析数据:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "goToVC" { guard let content = sender as? Response.Content, let vc = segue.destination as? ViewController else { return } vc.name = content.Name vc.message = content.Message } }
方案二:通过索引从数据源取数据
定义一个存储选中索引的变量,在prepare方法中直接从数据源获取对应数据:
var selectedIndex: Int? func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { selectedIndex = indexPath.row performSegue(withIdentifier: "goToVC", sender: nil) }
修改prepare(for:sender:)方法:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if segue.identifier == "goToVC" { guard let index = selectedIndex, let content = self.responseDec?.array[index], let vc = segue.destination as? ViewController else { return } vc.name = content.Name vc.message = content.Message } }
两种方案都避免了全局变量带来的状态不一致问题,直接从可靠的数据源获取当前选中行的数据,确保传递给目标ViewController的是最新且正确的内容。
内容的提问来源于stack exchange,提问作者anderson
相关产品推荐
相关产品推荐

