美文网首页
*** Assertion failure in -[ShopI

*** Assertion failure in -[ShopI

作者: suoluomen | 来源:发表于2019-05-17 14:21 被阅读0次
    • iPhone系统
      iOS 9.2 iOS 9.3.5 (12.0系统未出现崩溃)
    • 布局情况
      一个collectionView中有5个section,第一个section的header与其余的header不同,并且只有最后一个section有footer,其他section没有footer。
    • 崩溃操作
      当后台返回数据中,只给出了一个section的数据,其余四个section没有数据。即:只显示第一个section的header和items。
      此时发生崩溃,崩溃在返回header 和 footer的数据源方法处,报出断言失败 。
      *** Assertion failure in -[ShopInfoCollectionView _dequeueReusableViewOfKind:withIdentifier:forIndexPath:]
      或者
      *** Assertion failure in -[UICollectionViewData layoutAttributesForSupplementaryElementOfKind:atIndexPath:]
    • 代码书写
    // 初始化方法中注册 item header footer
    - (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout*)layout
    {
        self = [super initWithFrame:frame collectionViewLayout:layout];
        if(self) {
            [self registerClass:[CollectionCell class] forCellWithReuseIdentifier:@"cell"];
            [self registerClass:[CollectionHeader_1 class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"CollectionHeader_1"];
           [self registerClass:[CollectionHeader_2 class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"CollectionHeader_2"];
            [self registerClass:[CollectionFooter class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"CollectionFooter"];
        }
        return self;
    }
    
    // 返回item的size
    - (CGSize)collectionView:(UICollectionView*)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath*)indexPath{
           return CGSizeMake((375 - 30)*0.5, (375 - 30)*0.5*1.5);
    }
    
    // 返回header的size
    - (CGSize)collectionView:(UICollectionView*)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section{
        if(section ==0){
            return CGSizeMake(375, 100);
        }else{
                return CGSizeMake(375, 70);
            }
      }
    
    // 返回footer的size
    - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section{
        if (section == _sourceArr.count - 1){
            return CGSizeMake(375, 50);
    }else{
            return CGSizeZero;
        }
    }
    
    // 返回 item
    -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
            CollectionCell *item = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
            return item;
    }
    
    // 返回header 和 footer
    - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{
        
        if (indexPath.section == 0){
    // *****************崩溃在这个位置*********************
            CollectionHeader_1 *header = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"CollectionHeader_1" forIndexPath:indexPath];
    
            return header;
        }else if (indexPath.section == _sourceArr.count - 1){
            if (kind == UICollectionElementKindSectionHeader){
                CollectionHeader_2 *header = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"CollectionHeader_2" forIndexPath:indexPath];
                return header;
            }else{
                CollectionFooter *footer = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"CollectionFooter" forIndexPath:indexPath];
                return footer;
            }
        }else{
            CollectionHeader_2 *header = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"CollectionHeader_2" forIndexPath:indexPath];
            return header;
        }
    }
    
    
    • 原因分析
      在崩溃处,打印方法返回的kind值发现是:UICollectionElementKindSectionFooter ,但是上面代码中进入section==0的分支中并没有给出footer的类,所以报出断言失败。
      业务中第一个section不需要footer,所以一开始就没有给出第一个section的footer。但是在返回footer高度时,为section == 0的footer,设置了CGSizeZero。因为有了footer的size所以collectionView会去找一个secction的footer,很遗憾它没有找到,然后就崩了!!!
    • 解决方案
      修改 返回header 和 footer 方法中的代码逻辑,首先判断kind,确定初始化header还是footer,然后再根据不同的section返回不同的header、footer对象,具体如下:
    // 返回header 和 footer
    - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{
        if (kind == UICollectionElementKindSectionHeader){
         if (indexPath.section == 0){
            CollectionHeader_1 *header = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"CollectionHeader_1" forIndexPath:indexPath];
    
            return header;
        }else{
            CollectionHeader_2 *header = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"CollectionHeader_2" forIndexPath:indexPath];
            return header;
        }
    }else{
        CollectionFooter *footer = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"CollectionFooter" forIndexPath:indexPath];
        return footer;
    }   
    }
    
    • 疑问?
      目前原来的代码在iOS 12.0的系统上运行平稳,没有出现崩溃,而在iOS 9.x系统中崩溃必现,还不了解为什么?如果有人知道,请告知谢谢。

    相关文章

      网友评论

          本文标题:*** Assertion failure in -[ShopI

          本文链接:https://www.haomeiwen.com/subject/ydxoaqtx.html