有时SDWebImage中的应用程序崩溃(SDWebImageDownloaderOperation#cancelinternal)

时间:2016-04-18 02:35:00

标签: ios objective-c sdwebimage

我们在我们的应用程序中使用了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;
}

1 个答案:

答案 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;的代码,我可以帮到你。