SDWebImage操作未被取消

时间:2013-09-10 19:20:22

标签: iphone ios sdwebimage

我有一个表视图,其中包含几个Feed单元,每个单元格都有一些图像。我正在加载像这样的图像:

[timeLineCell.avatar setImageWithURL:[NSURL URLWithString:[feedAccount accountAvatarUrl]] placeholderImage:avatarPlaceholderImage options:SDWebImageRetryFailed];

这样可以正常工作,但是在慢速连接上,操作往往只是爬升而不是删除相同图像的旧操作。也就是说 - 如果我向下滚动并通过相同的单元格返回,它会将相同的图像添加到操作队列中以获得第二,第三,第四等时间。

我还试图在cellForRow中重复使用单元格时从下载队列中删除图像:

- (void)prepareForReuse {
    [super prepareForReuse];
    [self.avatar cancelCurrentImageLoad];
}

但似乎操作与SDWebImage的方法中的操作队列中的任何内容都不匹配,因此它实际上不会取消任何内容。如果我在共享管理器上运行cancelAll它可以工作,但它显然不理想。

我知道我只在这个单元格上显示一个图像,但我已经注释了除了这个图像加载以外的所有内容并且问题仍然存在。如果我注释掉头像图像并允许下载不同的图像(类似地加载),它也会持续存在。

有人对此有任何提示吗?

P.S。我已尝试将选项从SDWebImageRetryFailed更改为其他内容,包括根本没有选项,但它没有任何区别。

P.P.S。我正在使用CocoaPods(3.4)上提供的最新版SDWebImage。

2 个答案:

答案 0 :(得分:1)

为了解决这个问题,我实际上编辑了一下SDWebImage框架。 首先,我将以下方法添加到SDWebImageManager

- (void)cancelOperation:(id<SDWebImageOperation>)operation {
    @synchronized(self.runningOperations)
    {
        [self.runningOperations removeObject:operation];
    }
}

然后,我修改了- (void)cancel上的SDWebImageCombinedOperation方法:

- (void)cancel
{
    self.cancelled = YES;
    [[SDWebImageManager sharedManager] cancelOperation:self];
    if (self.cacheOperation)
    {
        [self.cacheOperation cancel];
        self.cacheOperation = nil;
    }
    if (self.cancelBlock)
    {
        self.cancelBlock();
        self.cancelBlock = nil;
    }
}

这并没有完全摆脱在队列中添加额外操作的问题,但是现有的失败的操作肯定会更快地被清除,因此问题不再是问题。我假设它似乎在队列中添加了更多操作,但这是因为现有的操作尚未检查其isCancelled标志。

答案 1 :(得分:0)

我也有这个问题很长一段时间。我真的不知道为什么这个策略不起作用,因为它似乎真的应该。我通过从同一框架切换到另一个API方法来解决问题。我没有使用速记UIImageView类别方法,而是切换到downloadWithURL:options:progress:completed。

这是我在UITableViewCell类中最终得到的结果:

@interface MyTableViewCell ()

@property (nonatomic, weak) id <SDWebImageOperation> imageOperation;

@end

@implementation MyTableViewCell

- (void)prepareForReuse {
    [super prepareForReuse];

    if (self.imageOperation) {
        [self.imageOperation cancel];
    }

    self.imageOperation = nil;
    [self.imageView setImage:self.placeholderImage];
}

- (void)configure {
    SDWebImageManager *manager = [SDWebImageManager sharedManager];
    self.imageOperation = [manager downloadWithURL:self.imageURL
                                           options:SDWebImageRetryFailed
                                          progress:nil
                                         completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished) {
                                             if (image) {
                                                 [self.imageView setImage:image];
                                             }
                                         }];
}

@end