High Sierra中的NSCollectionView内存泄漏?

时间:2018-06-18 20:00:28

标签: xcode macos memory-leaks storyboard nscollectionview

我注意到通过Instruments在NSCollectionView中发生了内存泄漏。当我追溯到代码时,它会显示以下特定行:

OnSelectrow

然后我在Xcode,内存调试器中查看它,并发现有一些未引用的项目导致泄漏。但是,并非collectionView.makeItem(withIdentifier: identifier, for: indexPath) as? DisplayableCellProtocol 创建的所有项目都在泄漏,其中一些是正常的,但有些项目甚至没有显示。

管理正常的未泄露项目就像这个图表 correct

泄露的是这样的(没有任何联系): wrong

这是正常的,其他人是否也有同样的问题?有谁知道如何正确解决这个问题?这与使用xib设计项目视图有什么关系吗?

以下是一些可能有助于了解情况的代码:

makeItem

ServiceCell的定义是:

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
}

不确定代码是否有用。我试图找到我自己的代码中是否有任何错误,但还没有找到任何错误。

与此同时,我发现了很多其他漏洞,其中大部分都指向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. } } 线 enter image description here

更新:我再看一遍。所以每次它会使实际需要的项目数量增加一倍。例如,我需要2个单元格,它将创建4个而不是2个,其中两个是泄露的单元格。有什么想法吗?

3 个答案:

答案 0 :(得分:6)

这终于解决了。在创建具有xib文件的,从NSCollectionViewItem继承的类时,默认情况下,在xib中,文件所有者的类设置为之前创建的子类。当我们在xib中添加自定义对象时,需要将其设置为空。

solution

答案 1 :(得分:0)

我没有在High Sierra看到这样的泄漏。你有可以分享的代码吗?从提供的内容中排除故障很困难。

答案 2 :(得分:0)

如果您的 delegatedataSource 被(弱?)设置为 NSCollectionView 本身,我假设您会看到这个问题。我在 MacOSX 10.14.6 上的这个设置有点问题。

在代表如此连线的情况下,我通过为 willDisplayItemdidEndDisplayingItem 引入空存根而“解决”了这个问题。这样,内存泄漏就消失了。

我的收藏视图内容是 48 项;在没有这些存根的情况下,itemForRepresentedObjectAtIndexPath(称为 makeItemWithIdentifier)的第一次返回使我的应用程序的内存使用率飙升。

我现在正在将此集合视图重新定位到 NSViewController 中以避免这些恶作剧。