【问题标题】:Memory leaks when calls dequeueReusableCell(withIdentifier:for:) swift快速调用 dequeueReusableCell(withIdentifier:for:) 时内存泄漏
【发布时间】:2019-04-03 18:20:11
【问题描述】:

我必须展示几个不同的单元格。我为此调用了tableView(_:cellForRowAt:),在该方法中,我为UITableViceCell的不同类别使用了两个不同的ID

这是一个简单的代码:

class SimpleView: UITableViewController {
...

let cellIdMain = "JournalMainCellID"
let cellIdExtra = "JournalMainSceneAddNewID"

...

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

    if indexPath.row == journals.count {
        guard let cellAdding = tableView.dequeueReusableCell(withIdentifier: cellIdExtra, for: indexPath) as? JournalMainSceneAddNew else {
            fatalError("Cannot connect to the cell")
        }
        return cellAdding
    }

    guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdMain, for: indexPath) as? JournalMainSceneCell else {
        fatalError("Cannot connect to the cell")
    }
    cell.numberOfCountriesLabel.text = "\(journals[indexPath.row].numberOFCountries)"
    return cell
}
}

当我试图查找内存泄漏时,我发现:

当我点击我找到的详细信息时:

为什么会这样?它看起来非常简单明了。

更新:图片已更新。

【问题讨论】:

  • 是的,但是 XCode 指出了代码的不同部分。
  • @matt 抱歉,这是真的。它是相同的。 Xcode 显示每行 32 字节的内存泄漏。我会更新图片。
  • @matt - 然后我在tableView(_:cellForRowAt:) 中使用字符串值而不是cellIdMaincellIdExtra 看起来内存泄漏消失了...奇怪,所有ID 都是let 常量...
  • 我也试过使用guard let cellAdding = tableView.dequeueReusableCell(withIdentifier: "\(cellIdExtra)", for: indexPath) else...,没有任何效果。

标签: ios swift memory-leaks


【解决方案1】:

如果条件仅在一种情况下有效,因为 indexpath.row 将仅等于 count 即使它不起作用,因为在通过 if 之后它会在 if 之后执行代码块 这意味着你的 if 块是浪费 为什么要使用 cell.delegate??

【讨论】:

  • tableViewController 应该显示不同的最后一行。这就是我使用 If contition 的原因。由于使用了 swipecellkit 外部库,因此需要委托。但问题是内存泄漏,它在dequeueReusableCell 方法中。没看懂
  • 然后把剩下的写在else部分
  • 最好在 indexpath.row 上使用 switch,因为 case 等于 journals.count,默认只有 2 个 case
【解决方案2】:

使用以下代码更新您的代码。

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

    if indexPath.row == journals.count {

        let cellAdding: JournalMainSceneAddNew = {
            guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdExtra) as? JournalMainSceneAddNew else {                
                return JournalMainSceneAddNew(style: UITableViewCellStyle.value1, reuseIdentifier: cellIdExtra)
            }
            return cell
        }()

        return cellAdding
    }

    let cell: JournalMainSceneCell = {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdMain) as? JournalMainSceneCell else {                
            return JournalMainSceneCell(style: UITableViewCellStyle.value1, reuseIdentifier: cellIdMain)
        }
        return cell
    }()

    cell.numberOfCountriesLabel.text = "\(journals[indexPath.row].numberOFCountries)"
    return cell
}

【讨论】:

  • 然后我直接使用字符串值,而不是tableView(_:cellForRowAt:) 中的cellIdMaincellIdExtra 看起来内存泄漏消失了...奇怪,所有ID 都保持不变...
  • 是的,你可以直接使用字符串值作为标识符。
  • 但是为什么我不能在tableView(_:cellForRowAt:)中使用字符串的let常量呢?
  • 我将再次阅读 swift 文档,但据我所知,它让常量和字符串类 - 这里不应该有任何强引用循环
  • @Alex 我面临同样的问题。有什么对你有用的吗?
猜你喜欢
  • 1970-01-01
  • 2014-06-24
  • 2021-04-01
  • 2016-12-07
  • 1970-01-01
  • 1970-01-01
  • 2010-12-01
  • 2017-01-13
  • 1970-01-01
相关资源
最近更新 更多