【问题标题】:Table Refresh doubles number of Array items表刷新使数组项的数量翻倍
【发布时间】:2016-12-18 16:38:35
【问题描述】:

我有来自 CloudKit 的静态数据(3 个值),问题是当我刷新 UITableView 时,我得到 6 个值而不是 3 个值

我不知道为什么它不刷新并丢弃Array 中的旧数据,而是保留旧数据并向其中添加相同的数据Array

初始UITableView设置

func getData() {
    cloud.getCloudKit { (game: [Game]) in
        var teamColorArray = [String]()
        for item in game {
            let itemColor = item.teamColor
            teamColorArray.append(itemColor)
            print("TCA in: \(teamColorArray)")
        }

        self.teamColorArray = teamColorArray
        self.tableView.reloadData()
    }
}

打印:["CC0033", "FDB927", "E3263A"]

拉动UIRefreshControl时刷新数据

@IBAction func refreshData(_ sender: Any) {
    self.teamColorArray.removeAll()
    getData()
    self.refreshControl?.endRefreshing()
}

打印:[“CC0033”、“FDB927”、“E3263A”、“CC0033”、“FDB927”、“E3263A”]

我想我已经把它缩小到某种方式 game 在函数 getData() 被递增到 6 个项目的计数。我不确定如果它从CloudKit 中提取所有新数据,为什么它不会总是停留在 3 个项目上,但也许我不明白调用完成处理程序会使值加倍,也许我需要removeAll在里面?我真的不确定

有没有人发现我做错了什么,或者他们会做些什么来修复我的代码?

谢谢!

【问题讨论】:

  • 如果您希望或期望您的数组是唯一的,那么只需使用集合而不是数组。这样你就不会得到重复的数据。请参阅帖子 (stackoverflow.com/questions/27624331/…)。
  • @ErionV 是的好信息,我实际上在想我可能最终会尝试一个 Set,但不确定我是否在我目前所拥有的东西中搞砸了一些更简单的东西。感谢您重申尝试套装的可能性!

标签: ios swift uitableview uirefreshcontrol completionhandler


【解决方案1】:

可能与您对 cloudkit 的异步调用有关。我对刷新控制不太熟悉,但这里有一种方法可以解决你的问题,也可以让你的代码更简洁。

func getData(_ completion: () -> ()) {
  teamColorArray.removeAll()
  cloud.getCloudKit { [weak self] (game: [Game]) in
    guard let unwrappedSelf = self else { return }
    var updatedColorArray = [String]()
    game.forEach { updatedColorArray.append($0.teamColor) }
    unwrappedSelf.teamColorArray = updatedColorArray
    completion()
 }
}

现在当你调用 getData 时,它看起来像这样

getData { 
   DispatchQueue.main.async { [weak self] in
     self?.tableView.reloadData()
     self?.refreshControl?.endRefreshing()
  }
}
  • 你添加了weak self来消除保留循环的可能性

  • 确保从主线程更新 UI

  • 当您知道数组已正确设置时调用 reloadData 和 endRefreshing

我将 teamColorArray.removeAll() 放在 getData 函数中,因为您似乎每次都需要调用它,这样您就不必每次都在函数之前添加它。

【讨论】:

  • 看起来不错,让我们等待OP的回应。
  • 这对我不起作用,但它看起来比我的优雅得多,所以我肯定会根据你的建议换掉我的 for 循环等。我想我可能需要清空在(game: [Game]) 部分或其他东西中传递给我的数组,因为它可能不会清空该部分或其他东西。不确定这是否有意义,但我会尝试一下
  • 问题不应该来自这个函数,所以如果您需要更多帮助,只需发布​​更多代码,我会看看。
  • 感谢您将我带到更快捷的代码版本。在我重构时,有什么理由不能将var updatedColorArray = [String]() + game.forEach { updatedColorArray.append($0.teamColor) } + unwrappedSelf.teamColorArray = updatedColorArray 简化为game.forEach { unwrappedSelf.teamColorArray.append($0.teamColor) }?当我尝试它时,它又回到了加倍之类的东西,我不确定它是否与[weak self] 的东西有关,或者究竟是什么,但我确定我错过了一些东西。有什么想法吗?
  • 为了简化您的代码,您可能甚至不想获得颜色,而只是制作一系列游戏。然后在 tableView.cellForRow 中,从 gameObject 中分配 teamColor。然后在关闭中将您的游戏数组设置为新的游戏数组。应该更快,因为您不需要遍历闭包中的每个游戏对象来获取 teamColor 属性
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-25
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-13
相关资源
最近更新 更多