0

I have an NSCollectionView specified as both my DataSource and my Delegate.

I have two issues:

  1. Rather than doing the registerClass method, attempting to instead use the 3 lines of commented code with the (non-nil) protoNib means of registering with an NSCollectionView causes theItem to always be nil.

  2. Using the class registry option, all works mostly fine. But if I remove the willDisplayItem and didEndDisplayingItem stubs, the system eats up gobs of memory on its first call to itemForRepresentedObjectAtIndexPath (with thousands of internal calls to these two stubs) and eventually crashes. Instruments shows thousands of 4k @autoreleasepool content items being created by AppKit.

Any idea why this might be happening?

-(void)awakeFromNib {
    [self registerClass:[MECollectionViewItem class] forItemWithIdentifier:@"EntityItem"];
//  NSString *nibName = NSStringFromClass([MECollectionViewItem class]);
//  NSNib *protoNib = [[NSNib alloc] initWithNibNamed:nibName bundle:nil];
//  [self registerNib:protoNib forItemWithIdentifier:@"EntityItem"];
    
    __weak typeof(self) weakSelf = self;
    [self setDelegate:weakSelf];
    [self setDataSource:weakSelf];
    ...
}

- (MECollectionViewItem *)collectionView:(NSCollectionView *)collectionView
     itemForRepresentedObjectAtIndexPath:(NSIndexPath *)indexPath;
{
        MECollectionViewItem *theItem = [self makeItemWithIdentifier:@"EntityItem"
                                                        forIndexPath:indexPath];
        return theItem;
}

-(void)collectionView:(NSCollectionView *)collectionView
      willDisplayItem:(NSCollectionViewItem *)item
forRepresentedObjectAtIndexPath:(NSIndexPath *)indexPath
{
}

-(void)collectionView:(NSCollectionView *)collectionView
 didEndDisplayingItem:(nonnull NSCollectionViewItem *)item
forRepresentedObjectAtIndexPath:(nonnull NSIndexPath *)indexPath
{
}
zzyzy
  • 973
  • 6
  • 21
  • I’m not losing my mind. https://twitter.com/bitemybyte/status/1147135248913829888 – zzyzy Dec 25 '20 at 06:56
  • Does this answer your question? [NSCollectionView memory leak in High Sierra?](https://stackoverflow.com/questions/50916659/nscollectionview-memory-leak-in-high-sierra) – Willeke Dec 25 '20 at 08:22
  • Are issue 1 and 2 related? Please ask a question for each issue. – Willeke Dec 25 '20 at 08:40
  • Issue 2: to clarify, I have 48 items to create. Without the the stubs, only one call to makeItemWithIdentifier happens for the first item, then the app beachballs with memory eventually exhausted. – zzyzy Dec 25 '20 at 16:44
  • Ask issue 1 in a new question please. – Willeke Dec 26 '20 at 09:20

1 Answers1

0

The Appkit classes are not designed to be their own delegate. NSCollectionView implements several NSCollectionViewDelegate methods and calls the delegate. I don't know why it's implemented like this and it doesn't feel right but it is what it is. If the collection view is its own delegate and a delegate method isn't implemented in the subclass then the call causes an infinite loop. Solution: don't set delegate to self.

Willeke
  • 14,578
  • 4
  • 19
  • 47