DanubePM
DanubePM

Reputation: 1781

My view controllers are being retained (I think), but I can't find a strong reference

I'm dealing with a memory leak and the debuggers haven't been much help. I noticed that several of my View Controllers were still in memory after they were dismissed. My assumption is that there is a strong reference, and I've been searching for that.

As I was playing around with leaks, I noticed a command called traceTree. I ran it with the address of the object-which-shouldn't-exist. It reported the following....

2 <CaptureViewController 0x7fee7a008800> [1536]
  2 <WaterfallCollectionViewLayout 0x7fee47c0b450> [368]   +264: delegate 0x7fee47c0b558
    2 <UICollectionView 0x7fee7a060e00> [3072]  +1744: __strong _layout 0x7fee7a0614d0
      1 0x7fee47c10590 [112]    +24:  0x7fee47c105a8 --> offset 2
      + 1 0x7fee7b028000 [16896] +10600:  0x7fee7b02a968
      +   1 Region libobjc.A.dylib __DATA __bss: 'objc::AssociationsManager::_mapStorage' 0x7fff89c160c8
      1 0x7fee67d02c30 [304]   +112:  0x7fee67d02ca0
        1 0x7fee67d02100 [304]     +8:  0x7fee67d02108
          1 0x7fee7900be00 [8704]  +2432:  0x7fee7900c780
            1 Region dyld __DATA __common: '_main_thread' + 800 0x1155e1060

Question: I don't really know what I'm looking at. Is this telling me that there's a strong reference from WaterfallCollectionViewLayout to CaptureViewController?

CaptureViewController is a UICollectionViewController and WaterfallCollectionViewLayout is a custom UICollectionViewLayout. The layout class uses the collection view controller as a delegate for layout purposes. It looks like this...

protocol WaterfallCollectionViewLayoutDelegate: class {
    func waterfallCollectionViewLayout(_ waterfallCollectionViewLayout: WaterfallCollectionViewLayout, sizeForCellAt indexPath: NSIndexPath, fitting size: CGSize) -> CGSize
}

class WaterfallCollectionViewLayout: UICollectionViewLayout {

    /* ... */

    weak var delegate: WaterfallCollectionViewLayoutDelegate!

    /* ... */

}

Any suggestions or advice would be greatly appreciated.

Upvotes: 5

Views: 727

Answers (1)

DanubePM
DanubePM

Reputation: 1781

I've figured it out, ya'll. Turns out it was a closure.

I was implementing the new diffable datasource which requires a closure for providing cells and an optional closure for providing headers. I wasn't using "weak self" in these closures.

The takeaway is that the debugger can be misleading: it showed my UICollectionViewLayout as the only reference to my object, even though that reference was weak. I discovered the true culprit by setting this particular reference to nil in viewDidDisappear, and suddenly the debugger became a whole lot more helpful.

Collection View Diffable Datasource

Advances in UI Data Sources - WWDC 2019 - 220

Upvotes: 9

Related Questions