SDWebImage operations not being canceled

て烟熏妆下的殇ゞ 提交于 2020-01-02 16:57:19

问题


I have a table view that includes several feed cells that each have a few images a piece. I'm loading in the images like this:

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

This works fine, but on slow connections the operations tend to just climb instead of removing old operations for the same images. That is -- if I scroll down and back up through the same cells, it adds the same images into the operation queue for a second, third, fourth, etc time.

I'm also attempting to remove images from the download queue when the cell gets reused like this in cellForRow:

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

But it seems like the operation doesn't match anything in the operation queue in SDWebImage's methods, so it doesn't actually cancel anything. If I run cancelAll on the shared manager it works, but it's obviously not ideal.

I'm aware I'm only showing one image on this cell, but I have commented out everything except for this image loading and the problem persists. It also persists if I comment out the avatar image and allow a different image (loaded similarly) to download instead.

Anyone have any tips on this?

P.S. I've tried changing the options from SDWebImageRetryFailed to other things including no options at all, but it made no difference.

P.P.S. I'm using the latest version of SDWebImage available on CocoaPods (3.4).


回答1:


To solve this problem, I actually edited the SDWebImage framework a little bit. First, I added the following method to SDWebImageManager:

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

Then, I modified the - (void)cancel method on 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;
    }
}

This didn't completely get rid of the problem of extra operations being added on the queue, but the existing failed ones definitely get cleared out much faster, and as such the problem winds up not being an issue anymore. I'm assuming it appears there are more operations being added in the queue, but that's because the existing ones haven't checked their isCancelled flags yet.




回答2:


I had this issue as well for a long time. I don't really know why this strategy doesn't work because it seems like it really should. I fixed the issue by switching to another API method from the same framework. Instead of using the shorthand UIImageView category method I switched to downloadWithURL:options:progress:completed instead.

This is what I ended up with in my UITableViewCell class:

@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


来源:https://stackoverflow.com/questions/18727165/sdwebimage-operations-not-being-canceled

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!