かなり複雑なcollectionViewセルを取得しましたが、collectionViewで本当に速くスクロールすると、アプリがクラッシュすることに気づきました。
私が得たエラーの1つはこれです:
negative or zero sizes are not supported in the flow layout
私は浮動小数点値を返すだけであることに気づきました500、私のUICollectionView sizeForItemAtIndexPath:
メソッドでは、クラッシュしません。
コレクションビューに動的なセルの高さがあります。
このライブラリを使用してsizeForItemAtIndexPath:
メソッドでHTML属性付き文字列を解析しています:
https://github.com/mmislam101/HTMLAttributedString
上記のエラーメッセージが特に発生する原因を知っている人はいますか?
このクラッシュに関連してBugsenseレポートに表示される他のエラーは次のとおりです。
-[__ NSArrayM objectAtIndex:]:範囲[0 .. 1]を超えるインデックス2
これは、スクロールが速すぎる場合に発生します= /
Bugsenseスタックトレースは、クラッシュオーダーメソッドの呼び出しが次のとおりであることを示しています。
1)collectionView:layout:sizeForItemAtIndexPath:
2)calculateFeedCellHeightForIndexPath:(これは私自身のメソッドの1つであり、Appleのメソッドではありません)
3)dynamicHeightForHTMLAttributedString:UsingWidth:AndFont:(これはAppleのメソッドではなく、私の独自のメソッドの1つです)
4)HTMLAttributedString attributedStringWithHtml:andBodyFont:行35
5)HTMLAttributedString attributedString 79行目
6)scrollViewDidScroll:174行
7)setFeedFooterHeight:animated:line 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];
}
}
ただし、上記のようにTestflightではなくXcodeから直接アプリを実行すると、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;
}
他のスレッドでuicollection.isTrackingがfalseになるまでuicollectionviewリロードをラップすることについて何か読みましたか?
私はそれを試しましたが、助けにはならなかったようです。
OK、そのエラーの原因を偶然見つけました。
[collectionView.collectionFlowLayout invalidateLayout];
呼び出しに関連しています。
1.0秒の遅延を追加したところ、問題は解消されたようです。
これは、UICollectionViewのデリゲート/データソースメソッド、および/またはNSAttributedStringに関連するiOS 8のバグだと思います。
sizeForItemAtIndexPath:
でHTMLからNSAttributedString
を作成することで、同じクラッシュを1つのプロジェクトで取得できます。属性付きの文字列を作成する場合firstnumberOfRows:
では、これによりクラッシュが停止します。そのため、UIKitの何かが正しく初期化されていないか、HTMLパーサーとUICollectionView
サイジングメソッドのいずれかでバッファが共有されている可能性があります。
注: 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ベータ2をダウンロードしてテストし、またレポートします。
コードで、collectionViewLayout.itemSizeを定義する場所で、サイズに負の値またはゼロの値が含まれていないことを確認してください
これを使って
func collectionView(_ collectionView:UICollectionView、layout collectionViewLayout:UICollectionViewLayout、sizeForItemAt indexPath:IndexPath)-> CGSize {
if width <= 0 || height <= 0{
return CGSize(width: 0, height: 0)
}
}
間違った計算ロジックのため、幅を-6からsizeForItemAtに送信していたため、アプリがクラッシュしました
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: width, height: height)
}
幅&高さは常に非負の数(> = 0)である必要があります