我通过 Instruments 注意到 NSCollectionView 中的内存泄漏。当我追踪到代码时,它显示了下面的特定行:

collectionView.makeItem(withIdentifier: identifier, for: indexPath) as? DisplayableCellProtocol

然后我在 Xcode、内存调试器中查看了它,发现有一些未引用的项目导致了泄漏。但是,并非makeItem创建的所有项目都在泄漏,其中有些是正常的,但有些甚至没有显示。

托管正常未泄漏项目如下图
xcode - High Sierra 中的 NSCollectionView 内存泄漏?-LMLPHP

而泄露的是这样的(没有任何连接):
xcode - High Sierra 中的 NSCollectionView 内存泄漏?-LMLPHP

正常吗,有没有人遇到同样的问题?有谁知道如何正确解决这个问题?这与使用 xib 设计项目 View 有什么关系吗?

以下是一些可能有助于了解这种情况的代码:
func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
  let data = datasource[indexPath.item]
  let identifier: String = "ServiceCell"
  // Next line is where the leak occurs
  guard let cell = collectionView.makeItem(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: identifier), for: indexPath) as? ServiceCell else {
      return ServiceCell(nibName: NSNib.Name("ServiceCell.xib"), bundle: Bundle.main)
  }
  cell.iconView.image = data.icon
  cell.serviceLabel.stringValue = data.name
  cell.introLabel.stringValue = data.content
  cell.highlighted = false
  return cell
}

ServiceCell 的定义是:
class ServiceCell: NSCollectionViewItem {
  @IBOutlet weak var iconView: NSImageView!
  @IBOutlet weak var serviceLabel: NSTextField!
  @IBOutlet weak var cmdLabel: NSTextField!
  @IBOutlet weak var introLabel: NSTextField!

  override func viewDidLoad() {
    super.viewDidLoad()
    // Do view setup here.
  }
}

不确定代码在这里是否有帮助。我试图找出我自己的代码中是否有任何错误,但还没有找到。

同时,我发现了很多其他的泄漏,其中大部分都指向 makeItem
xcode - High Sierra 中的 NSCollectionView 内存泄漏?-LMLPHP

更新:我又看了一遍。所以每次它都会使实际需要的物品数量增加一倍。例如,我需要 2 个单元格,它将创建 4 个而不是 2 个,其中两个是泄漏的单元格。有任何想法吗?

最佳答案

这终于解决了。创建一个继承自NSCollectionViewItem的类并创建xib文件时,xib中 File Owner 的类默认设置为之前创建的子类。当我们在xib中添加自定义对象时,这需要设置为空。

xcode - High Sierra 中的 NSCollectionView 内存泄漏?-LMLPHP

关于xcode - High Sierra 中的 NSCollectionView 内存泄漏?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50916659/

10-15 15:27