SDWebImage库里的函数:
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock;
{
[self cancelCurrentImageLoad];
self.image = placeholder;
if (url)
{
__weak UIImageView *wself = self;
id<SDWebImageOperation> operation = [SDWebImageManager.sharedManager downloadWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished)
{
__strong UIImageView *sself = wself;
if (!sself) return;
if (image)
{
sself.image = image;
[sself setNeedsLayout];
}
if (completedBlock && finished)
{
completedBlock(image, error, cacheType);
}
}];
objc_setAssociatedObject(self, &operationKey, operation, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
}
在block中用到了self,self会被block retain,而_observer会copy一份该block,就是说_observer间接持有self,同时当前的self也会retain _observer,最终导致self持有_observer,_observer持有self,形成retain
cycle。
对于在block中的retain
cycle,在2011 WWDC Session #322 (Objective-C Advancements in Depth)有一个解决方案weak-strong
dance,很漂亮的名字
在block中使用self之前先用一个__weak变量引用self,导致block不会retain
self,打破retain cycle,然后在block中使用wself之前先用__strong类型变量引用wself,以确保使用过程中不会dealloc。简而言之就是推迟对self的retain,在使用时才进行retain。这有点像lazy
loading的意思。
注:iOS5以下没有__weak,则需使用__unsafe_unretained。
本文探讨了在SDWebImage库中如何通过使用weak-strong dance来避免在block中形成的retain cycle,以防止对象被错误地持有,从而避免内存泄漏。
2267

被折叠的 条评论
为什么被折叠?



