在阅读 AFNetworking
的源码的时候,在 AFURLResponseSerialization.m
文件中看到如下代码:
@interface UIImage (AFNetworkingSafeImageLoading)
+ (UIImage *)af_safeImageWithData:(NSData *)data;
@end
static NSLock* imageLock = nil;
@implementation UIImage (AFNetworkingSafeImageLoading)
+ (UIImage *)af_safeImageWithData:(NSData *)data {
UIImage* image = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
imageLock = [[NSLock alloc] init];
});
[imageLock lock];
image = [UIImage imageWithData:data];
[imageLock unlock];
return image;
}
@end
这段代码就是给 UIImage
添加了一个分类,可以通过 NSData
获取 UIImage
,但是在转化过程中调用 imageWithData:
的前后加了锁。
原因是什么呢?
查了一下 AFN 的 issue,看到 Fix for issue #2572 Crash on AFImageWithDataAtScale when loading image。
UIImage initWithData is not thread safe. In order to avoid crash we need to serialise call.
UIImage initWithData
并不是线程安全的。为了避免崩溃,需要按顺序调用,所以加了线程锁。