我已经使用AFNetworking在我的项目中下载和缓存图像,但我想用最轻的内部类别替换框架,显然我在调度队列中面临很多问题,而且我有很难调试它们。
这是我现在正在使用的category,对于少量同时下载没有任何问题,但是,如果我开始大量下载,它看起来像应用程序挂起了无穷无尽的负载。
我需要一些帮助调试,我想了解我在这里缺少的东西。
以下是两个主要功能:
- (void) imageWithUrl: (NSURL*) imageUrl placeHolderImage: (UIImage *) placeHolderImage shouldAlwaysRefresh: (BOOL) shouldRefresh {
self.image= placeHolderImage;
TMCache *sharedCache = [TMCache sharedCache];
[sharedCache trimToDate: [NSDate dateWithTimeIntervalSinceNow: -(60.0*24.0*7.0)]];
UIImage *cachedImage = [sharedCache objectForKey: [imageUrl absoluteString]];
if(cachedImage){
self.image = cachedImage;
if(shouldRefresh)
[self fetchImageFromUrl: imageUrl];
}
else{
[self fetchImageFromUrl: imageUrl];
}
}
- (void) fetchImageFromUrl: (NSURL *) imageUrl{
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_async(queue, ^{
NSData *imageData = [NSData dataWithContentsOfURL:imageUrl];
UIImage *image = [UIImage imageWithData:imageData];
if(image){
[[TMCache sharedCache] setObject:image forKey: [imageUrl absoluteString]];
dispatch_sync(dispatch_get_main_queue(), ^{
self.image = image;
});
}
});
}
答案 0 :(得分:0)
您的问题很可能是dispatch_sync
返回主队列,在图片加载完成后创建deadlock。
解决这个问题最简单的方法就是将dispatch_sync
替换为dispatch_async
。
if(image) {
[[TMCache sharedCache] setObject:image forKey: [imageUrl absoluteString]];
dispatch_async(dispatch_get_main_queue(), ^{
self.image = image;
});
}
我没有看到任何理由使用dispatch_sync
,因为您已经在dispatch_async
区块内;这不应该对您的代码产生任何负面影响。事实上,如果可能的话,通常应该尽量避免使用dispatch_sync
,这恰恰是针对您在此处运行的问题。
旁注: AFNetworking实际上为您提供了相当多的代码。在使用自己的解决方案而不是AFNetworking之前,我会认真考虑三次。