我们在我们的应用程序中使用了SDWebImage Lib。(SDWebImage Version 3.7.2) 最近,app有时会异常终止。(在SDWebImageDownloaderOperation#cancelinternal中。)
以下是stacktrace。
Crashed: com.apple.main-thread EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0xxx Thread : Crashed: com.apple.main-thread 0 libobjc.A.dylib 0x180765bd0 objc_msgSend + 16 1 HOGE 0x1002a94d8 -SDWebImageDownloaderOperation cancelInternal 2 HOGE 0x1002a93ec -SDWebImageDownloaderOperation cancel 3 HOGE 0x1002ad63c __69-[SDWebImageManager downloadImageWithURL:options:progress:completed:]_block_invoke131 (SDWebImageManager.m:245) 4 HOGE 0x1002ae0f0 -SDWebImageCombinedOperation cancel 5 HOGE 0x1002b5380 -UIView(WebCacheOperation) sd_cancelImageLoadOperationWithKey: 6 HOGE 0x1002b0c74 -UIButton(WebCache) sd_cancelImageLoadForState: 7 HOGE 0x1002af578 -UIButton(WebCache) sd_setImageWithURL:forState:placeholderImage:options:completed: 8 HOGE 0x1002af3f8 -UIButton(WebCache) sd_setImageWithURL:forState:placeholderImage:options:
中止点正在跟随。
[imageButton sd_setImageWithURL:[NSURL URLWithString:url] forState:UIControlStateNormal placeholderImage:nil options:SDWebImageRetryFailed];
(它叫做Collection view cell的layoutSubviews)
CollectionView Cell的查看源代码。 头
#import <UIKit/UIKit.h>
#import "Photo.h"
@interface PhotoCollectionViewCell : UICollectionViewCell
@property (weak, nonatomic) IBOutlet UIButton *imageButton;
@property (strong, nonatomic) UIButton *likeButton;
@property (strong, nonatomic) Photo *photo;
@end
实施
@implementation PhotoCollectionViewCell
- (void)awakeFromNib
{
self.selectedBackgroundView = [[UIView alloc] initWithFrame:self.bounds];
self.selectedBackgroundView.backgroundColor = [BaseColorSet getColor1];
[_imageButton setBackgroundColor:[BaseColorSet getPhotoBackgroundColor]];
_imageButton.layer.cornerRadius = 2;
_imageButton.clipsToBounds = YES;
}
- (void)layoutSubviews
{
[super layoutSubviews];
NSString *url = [PhotoImgURL get_5:_photo];
if (!url) {
url = [NSString stringWithFormat:@"%@/%@/%@",S3_STORAGE_URL,[PhotoDirectory get_5],_photo.filename];
}
[_imageButton sd_setImageWithURL:[NSURL URLWithString:url] forState:UIControlStateNormal placeholderImage:nil options:SDWebImageRetryFailed];
_imageButton.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
_imageButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
_imageButton.imageView.contentMode = UIViewContentModeScaleToFill;
}
@end
MyCollectionViewController
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
PhotoCollectionViewCell *cell = (PhotoCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
cell.photo = [_photos objectAtIndex:indexPath.row];
[cell.imageButton addTarget:self action:@selector(imageButtonPushed:) forControlEvents:UIControlEventTouchUpInside];
[cell setNeedsLayout];
// add Load processing
if (indexPath.row == _photos.count-1 && !_isLast) {
Photo *photo = [_photos objectAtIndex:indexPath.row];
[self pagingMyView:photo];
}
return cell;
}
为什么会异常终止?
如何避免此错误?
(这是不良访问记忆?)
修改
感谢。 它尚未发布,并修改代码如下
PhotoCollectionViewCell(固定)。
@implementation PhotoCollectionViewCell
- (void)awakeFromNib
{
self.selectedBackgroundView = [[UIView alloc] initWithFrame:self.bounds];
self.selectedBackgroundView.backgroundColor = [BaseColorSet getColor1];
[_imageButton setBackgroundColor:[BaseColorSet getPhotoBackgroundColor]];
_imageButton.layer.cornerRadius = 2;
_imageButton.clipsToBounds = YES;
_imageButton.contentVerticalAlignment = UIControlContentVerticalAlignmentFill;
_imageButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill;
_imageButton.imageView.contentMode = UIViewContentModeScaleToFill;
}
-(void)prepareForReuse
{
[super prepareForReuse];
[_imageButton sd_cancelImageLoadForState:UIControlStateNormal];
}
@end
MyCollectionViewController(固定)
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
PhotoCollectionViewCell *cell = (PhotoCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
cell.photo = [_photos objectAtIndex:indexPath.row];
cell.imageButton.tag = cell.photo.photoId;
NSString *url = [PhotoImgURL get_5:cell.photo];
if (!url) {
url = [NSString stringWithFormat:@"%@/%@/%@",S3_STORAGE_URL,[PhotoDirectory get_5],cell.photo.filename];
}
[cell.imageButton sd_setImageWithURL:[NSURL URLWithString:url] forState:UIControlStateNormal placeholderImage:nil options:SDWebImageRetryFailed];
[cell.imageButton addTarget:self action:@selector(imageButtonPushed:) forControlEvents:UIControlEventTouchUpInside];
[cell setNeedsLayout];
// add Load processing
if (indexPath.row == _photos.count-1 && !_isLast) {
Photo *photo = [_photos objectAtIndex:indexPath.row];
[self pagingMyView:photo];
}
return cell;
}
答案 0 :(得分:1)
当您在UITableViewCell和UICollectionViewCell中使用SDWebImageView或SDWebImageButton时,您必须关注“单元格的重用时间&#39;和&#39;异步下载和设置图像时序&#39;。
当您快速滚动时会发生这种情况,因此当异步下载完成时,ui已被其他单元格重用。
为了避免这个错误(我猜),
在
中使用SDWebImage api- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
或
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
并使用&#39; __ block&#39;
抓住用户界面的指针如果你显示更多关于&#39; cellForItemAtIndexPath&#39;的代码,我可以帮到你。