ios - 为什么在 SDWebImage "strong reference to UIImageView might cause a crash in the nested block"中?

标签 ios objective-c uiimageview sdwebimage

我使用的是旧版本的 SDWebImage,但遇到如下崩溃:

0   libobjc.A.dylib                     0x000000019671bbd0 objc_msgSend + 16
1   UIKit                               0x0000000189932eac -[UIView(Rendering) contentMode] + 316
2   UIKit                               0x00000001899320e0 -[UIImageView _canDrawContent] + 144
3   UIKit                               0x0000000189932bac -[UIImageView _updateState] + 36
4   UIKit                               0x0000000189932b6c +[UIView(Animation) performWithoutAnimation:] + 88
5   UIKit                               0x0000000189c6b340 -[UIImageView _updateImageViewForOldImage:newImage:] + 452
6   UIKit                               0x0000000189932590 -[UIImageView setImage:] + 320
7   xxxx                                0x0000000100927adc __85-[UIImageView(WebCache) setImageWithURL:placeholderImage:options:progress:completed:]_block_invoke + 100

发生崩溃的 block 是:

        __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 setNeedsDisplay];
                                                 [sself setNeedsLayout];
                                             }
                                             if (completedBlock && finished)
                                             {
                                                 completedBlock(image, error, cacheType);
                                             }
                                         }];

然后我找到了一个SDWebImage的修复,commit comment是:

Removed strong reference to UIImageView which was causing a crash in the nested block

这是 commit .唯一的变化是删除 block 中 UIImageView 的强引用。

The commit

在 block 中使用强引用来保持一致性被广泛使用,但为什么SDWebImage会有这种变化。为什么这会导致崩溃?如果 UIImageView 会导致崩溃,还有什么会导致崩溃?

最佳答案

该修复程序可以解决的是 View 移除和/或销毁期间的竞争条件,其中正在释放内部渲染缓冲区,但可以及时应用保留以防止释放。然后,如果有什么东西触发写入那些现在消失的缓冲区,你就会得到那个段错误。

理论上,在直接访问原始指针且未充分保护其销毁的任何地方都可能遇到此问题。在实践中,除了基于 UIImage 的 API 之外,UIKit 级别的代码不太可能在任何地方遇到它,我想这将是一个相当深奥的竞争条件,在 View 拆卸开始之前小心取消所有异步更新应该完全消除;无论如何,您应该这样做以避免不必要的工作。

关于ios - 为什么在 SDWebImage "strong reference to UIImageView might cause a crash in the nested block"中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37246522/

相关文章:

ios - 尽管有背景音频功能和 session 类别,背景音频仍停止

iphone - 创建点击叠加说明 View

ios - 如何在允许设置 Root View Controller 的同时调整 UINavigationBar 的高度?

iphone - 如何在 UIWebView 中正确显示 TXT 或 ASCII 文件

iphone - 如何将字符串值从一个.m文件传递到另一个.m文件

iphone - 可以访问 iPhone 用户的音乐和视频

ios - Objective C 中具有相同函数名称的类别

ios - 彩色 UIImages 变得像素化

ios - 如何在 Objective C 中获取带有 subview 的 uiimageview 图像

ios - IAP的一次性消耗品是否仅限于游戏?