1

我有一个自定义 UICollectionViewLayout 子类。调用 prepareLayout 时,它会为单元格创建布局属性并缓存它们,然后在适当的时间返回它们。这一切正常。

我最近为 shouldInvalidateLayoutForBoundsChange: 添加了一个覆盖,这样当布局由于设备旋转而改变比例时,它会很好地布局。我现在看到的是应用程序有时会崩溃并显示一条消息:“[UICollectionViewLayoutAttributes copy]: message sent to deallocated instance”。在轮换事件期间接收到新数据时会发生这种情况。

据我所知,发生这种情况是因为 iOS 正在向 UICollectionViewLayoutAttributes 对象发送 [copy] 我从 layoutAttributesForItemAtIndexPath: 方法返回的数据,并且在接收到数据并调用 prepareLayout 之后。但我不明白的是,为什么 iOS 不会立即复制该项目,或者我如何在返回项目后将其保留一段适当的时间而不会泄漏内存。

回顾一下:

- prepareLayout {
    self.myCellAttributes = [NSMutableArray array];

    // calculate UICollectionViewLayoutAttributes for each cell, 
    // and store each in appropriate location ala:
    self.myCellAttributes[itemIndex]
}

- layoutAttributesForItemAtIndexPath:(NSIndexPath*)indexPath {
    // return appropriate attributes ala:
    return self.myCellAttributes[itemIndex];
}

-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
    CGRect oldBounds = self.collectionView.bounds;
    return CGRectGetHeight(newBounds) != CGRectGetHeight(oldBounds);
}

我最初的修复尝试是:

-(void)prepareForAnimatedBoundsChange:(CGRect)oldBounds {
    self.retainedAttributes = self.myCellAttributes;
}
-(void)finalizeAnimatedBoundsChange {
    self.retainedAttributes = nil;
}

我的想法是我会保留在动画期间返回的对象,所以如果在发生这种情况时有新数据进入,就不会有问题。这对行为没有任何明显的影响,所以我不知道如何确保属性保留正确的时间。

所以目前,我只是为 shouldInvalidateForBoundsChange 返回 NO,它消除了崩溃并且工作正常,除了单元格“捕捉”到新大小而不是平滑过渡。

非常感谢任何建议/建议/指针。

4

0 回答 0