sizeForItemAtIndexPath

sizeForItemAtIndexPath

我有一个相当复杂的collectionView单元,并且我注意到,如果我在自己的collectionView上滚动得非常快,它将使应用程序崩溃。

我得到的错误之一是:

negative or zero sizes are not supported in the flow layout

我注意到是否只返回浮点值,例如500,在我的UICollectionView sizeForItemAtIndexPath:方法中,它不会崩溃。

我的收藏夹 View 具有动态单元格高度。

我正在使用此库在sizeForItemAtIndexPath:方法中解析HTML属性字符串:

https://github.com/mmislam101/HTMLAttributedString

有谁知道导致上述错误消息特别发生的原因?

更新

我在Bugsense报表中也看到的与此崩溃相关的另一个错误是:

-[__ NSArrayM objectAtIndex:]:索引2超出范围[0 .. 1]

当我滚动太快时会发生这种情况=/

更新2

Bugsense stacktrace显示崩溃顺序方法调用为:

1)collectionView:layout:sizeForItemAtIndexPath:

2)calculateFeedCellHeightForIndexPath :(这是我自己的方法之一,而不是苹果公司的方法)

3)dynamicHeightForHTMLAttributedString:UsingWidth:AndFont:(这是我自己的方法之一,而不是Apple的方法)

4)HTMLAttributedString attributedStringWithHtml:andBodyFont:第35行

5)HTMLAttributedString attributedString第79行

6)scrollViewDidScroll:第174行

7)setFeedFooterHeight:动画:第124行

我的setFeedFooterHeight:animated:方法是:
-(void)setFeedFooterHeight:(CGFloat)newHeight animated:(BOOL)animated
{
    footerHeightConstraint.constant = newHeight;

    if(animated)
    {
        [UIView animateWithDuration:0.35 animations:^{
            [self layoutIfNeeded];  // <------ crash on this line it seems
        }];
    }
    else
    {
        [self.feedFooterView layoutIfNeeded];
    }
}

但是,当我直接从Xcode而不是上面的Testflight运行应用程序时,Xcode在上面的步骤5停止,这产生了这段代码:
- (NSAttributedString *)attributedString
{
    __block NSString *css       = @"<style>";

    [_cssAttributes enumerateObjectsUsingBlock:^(NSString *cssAttribute, NSUInteger idx, BOOL *stop) {
        css = [css stringByAppendingString:cssAttribute];
    }];

    css                         = [css stringByAppendingString:@"</style>"];
    NSString *htmlBody          = [_html stringByAppendingString:css];

    NSStringEncoding encoding   = NSUnicodeStringEncoding;
    NSData *data                = [htmlBody dataUsingEncoding:encoding];

    NSDictionary *options       = @{NSDocumentTypeDocumentAttribute         : NSHTMLTextDocumentType,
                                    NSCharacterEncodingDocumentAttribute    : @(encoding)};

    // app crashes here on this next line.
    NSAttributedString *body    = [[NSAttributedString alloc] initWithData:data
                                                                options:options
                                                     documentAttributes:nil
                                                                  error:nil];

    return body;
}

我在其他线程上阅读了一些有关包装uicollectionview重载直到uicollection.isTracking变为false的东西吗?

我尝试过,但似乎没有帮助。

更新3

好的,我不小心发现了该错误的原因。

它与[collectionView.collectionFlowLayout invalidateLayout];调用有关。

我添加了1.0秒的延迟,问题似乎消失了。

最佳答案

我认为这是与UICollectionView的委托(delegate)/数据源方法和/或NSAttributedString有关的iOS 8错误。

通过在NSAttributedString中从HTML创建sizeForItemAtIndexPath:,我可以在一个项目中发生相同的崩溃。 HTML解析器和numberOfRows:大小调整方法之一。

注意:iOS 7.1上的出现了另一个异常:“UICollectionView接收到索引路径不存在的单元格的布局属性:”

尝试这个实验:调用类似:

NSData *data = [@"<a href=\"http://www.google.com\">link</a>" dataUsingEncoding:NSUnicodeStringEncoding];
NSAttributedString *s = [[NSAttributedString alloc] initWithData:data options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType}  documentAttributes:nil error:nil];

在,说:
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section

这似乎迫使某些东西(也许是解析器?)被初始化,以至于当我在以下地方使用类似的代码时:
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath

它不会崩溃。疯狂的小镇。

我将下载8.1 beta 2并在那里进行测试,并将进行报告。

08-27 19:39