NSCollectionView memory leak in High Sierra?

血红的双手。 提交于 2020-12-30 07:31:58

问题


I have noticed a memory leak in NSCollectionView through Instruments. When I track down to the code, it shows the specific line below:

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

Then I looked it in Xcode, memory debugger, and find out there are some non-referenced items that caused the leak. However, not all items created by makeItem is leaking, some of them are normal, but some are not even shown.

Managed normal unleaked item is like this graph

And the leaked ones are like this (without any connections):

Is that normal, does anyone else has the same problem? Does anyone know how to correctly solve this problem? Does this have anything to do with using xib to design the items views?

Here are some code that may be helpful to understand the situation:

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
}

The definition of ServiceCell is:

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.
  }
}

Not sure if the code is helpful here. I have tried to find if there is any bug in my own code, but have not found any yet.

Meanwhile, I found a lot of other leaks, and most of them points to the makeItem line

Update: I have looked through it again. So every time it will double the number of items that is actually needed. For example, I need 2 cells, it will create 4 instead of 2, and two of them is the leaked ones. Any ideas?


回答1:


This is finally solved. When creating a class inherited from NSCollectionViewItem with creating an xib file, the class of the File Owner in the xib is set to the subclass created before by default. When we add a custom object in the xib, this needs to be set empty.




回答2:


I assume you're seeing this issue if your delegate and dataSource are (weakly?) set to the NSCollectionView itself. I had this slightly questionable setup on MacOSX 10.14.6.

With the delegates so-wired in, I questionably "solved" this by introducing empty stubs for willDisplayItem and didEndDisplayingItem. With that, the memory leaks went away.

My collection view content was 48 items; without these stubs, the first return from itemForRepresentedObjectAtIndexPath (which called makeItemWithIdentifier) beach-balled my app with memory usage shooting through the roof.

I'm in the process now of relocating this collection view into an NSViewController to avoid these shenanigans.



来源:https://stackoverflow.com/questions/50916659/nscollectionview-memory-leak-in-high-sierra

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!