viewForSupplementaryElementOfKind 在 "index 0 beyond bounds for empty array" 上崩溃



有时我会从viewForSupplementaryElementOfKind中获得此"索引0超出空数组的界限"错误。这种情况只是偶尔发生,通常集合加载正常,一切运行顺利。我想知道什么数组是空的?注册的细胞?(我试着通过代码或从界面构建器注册它们,但仍然没有改变)

我猜测,有时这个方法在加载集合时调用得太早,并且缺少一些尚未加载的数据。

有人能给我指个方向吗?

我的实现非常直接:(我在视图上使用了正确的重用标识符)

- (UICollectionReusableView *)collectionView:(UICollectionView *)theCollectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)theIndexPath{
UICollectionReusableView *theView;
if(kind == UICollectionElementKindSectionHeader)
{
    theView = [theCollectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"header" forIndexPath:theIndexPath];
} else {
    theView = [theCollectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"footer" forIndexPath:theIndexPath];
}
return theView;}

经过长时间的处理,我发现:

  • 如果您正在从Nib加载集合视图,并且在Nib文件的流布局中设置了非零的Section Header大小,则它将崩溃。

  • 如果你在Nib文件中设置流布局中节头的零大小,然后在viewDidLoad中适当设置它,它就不会崩溃:

    - (void)viewDidLoad
    {
        [super viewDidLoad];
        [self.collectionView registerNib:[UINib nibWithNibName:@"HeaderView" bundle:nil]
            forSupplementaryViewOfKind:UICollectionElementKindSectionHeader
            withReuseIdentifier:sHeaderViewIdentifier];
        [self.collectionView registerNib:[UINib nibWithNibName:@"Cell" bundle:nil] forCellWithReuseIdentifier:sCellIdentifier];
        UICollectionViewFlowLayout *layout = (UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout;
        layout.headerReferenceSize = CGSizeMake(self.collectionView.bounds.size.width, 50.f);
        [layout invalidateLayout];
    }
    

我仍然不知道为什么有时会崩溃,但似乎如果我用try-catch块包装这段代码,并分配一个视图,而不是去排队,那么集合将继续正常加载。。

if(kind == UICollectionElementKindSectionHeader) {
   theView = [theCollectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"header" forIndexPath:theIndexPath];
} 

转换为:

if(kind == UICollectionElementKindSectionHeader)
{
    @try {
        theView = [theCollectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"header" forIndexPath:theIndexPath];
    }
    @catch (NSException * e) {
        NSLog(@"Exception: %@", e);
        theView = [[UICollectionReusableView alloc] init];
    }
    @finally {
        return theView;
    }
} 

我知道分配UICollectionReusableView不是一个好主意,但现在或在我发现真正的问题之前,这是一个技巧性的解决方案。