我在 UICollectionView 中显示了很多图像(5k 图像)。这些图像已从远程服务器下载。当我从 UICollectionView 从上到下滚动(反之亦然) 5 到 6 次时,我的应用程序崩溃并且我收到错误“由于内存压力而终止应用程序”。请建议解决此问题。
- (NSInteger)collectionViewUICollectionView *)collectionView numberOfItemsInSectionNSInteger)section {
return urlLists.count;
}
- (UICollectionViewCell *)collectionViewUICollectionView *)collectionView cellForItemAtIndexPathNSIndexPath *)indexPath{
UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier"cellIdentifier" forIndexPath:indexPath];
UIImageView *cellImage=[[UIImageView alloc]init];
cellImage.frame=cell.contentView.bounds;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:[urlLists objectAtIndex:indexPath.row]]];
UIImage *image = [UIImage imageWithData:data];
UIImageJPEGRepresentation(image, 0.1);
data=nil;
dispatch_async(dispatch_get_main_queue(), ^{
cellImage.image=image;
});
});
NSLog(@"The Indexpath=%ld", indexPath.row);
[cell.contentView addSubview:cellImage];
return cell;
}
Best Answer-推荐答案 strong>
这里有三个层次的问题:
最严重的问题是每次使用单元格时,您都在向单元格添加一个新的 UIImageView 。但是单元格可以多次重复使用,因此您要向单元格添加许多 ImageView 。与所有其他 ImageView 关联的图像将占用内存。
在我看来,最简单/最好的解决方案是使用单元原型(prototype),在那里添加 ImageView ,并且不要以编程方式添加 ImageView 。或者,您可以通过编程方式添加 ImageView ,但请确保不要每次都添加新的 ImageView 。
顺便说一句,不要试图通过每次手动实例化一个新单元来关闭单元重用(正如这里其他人可能会建议的那样)。是的,这是一个简单的解决方案,但不是一个有效的解决方案。
一个更微妙的问题是你调用 UIImageJPEGRepresentation 我猜是为了减少所涉及的内存。这并不像你认为的那样。是的,它创建了一个压缩的 JPEG 表示,但您不使用它做任何事情。你只是丢弃它。
如果您想优化内存并且图像具有高分辨率,请考虑将图像大小调整为适合单元格的大小。见 UIImage resizing not working properly例如调整类别大小。
考虑使用 UIImageView 类别的SDWebImage或 AFNetworking ,它会延迟加载和缓存图像。
问题中的这段代码在启动异步检索之前不会正确重置 ImageView 。如果在图像检索完成之前重用单元格,它将不会处理这种情况。它可能会不必要地重新检索几秒钟前下载的图像。等等。
优雅地异步检索图像有很多问题,这两个类的 UIImageView 类别会为您处理很多这些细节。
关于ios - 滚动从远程服务器加载大量图像的 UICollectionView 时如何避免内存问题?,我们在Stack Overflow上找到一个类似的问题:
https://stackoverflow.com/questions/30374373/
|