AFNetworking图像缓存在内存警告时不会清空

时间:2014-02-04 00:02:13

标签: ios objective-c caching memory afnetworking

我有一个图像繁重的应用程序,我使用UIImageView + AFNetworking类别下载图像。

我注意到随着我加载越来越多的图像,我的内存占用率将继续上升。当我最终收到内存通知时,它没有释放任何内存 - 因此应用程序崩溃了。 我对此的理解是,AFNetworking使用一个名为NSCache的{​​{1}}子类,它应该自己处理内存警告。 Link 1 Link 2

使用一些脏黑客,我手动清除了共享缓存中的所有对象,并看到内存分配显着减少。如果不手动执行此调用,这似乎永远不会发生。

Allocation instruments

我在一个简单的应用程序中复制了这个,它下载了Imgur的首页并在简单的tableview中显示它。上面你可以看到为applpication完成的分配分析。

我试图删除任何花哨的东西,代码在某些地方很乱。它不包括我的脏黑客,所以它只是死于内存警告。您可以看到应用here

您需要在imgur设置应用程序才能使用它。

阅读github问题Mattt似乎表明它应该足够并且完全自我维护,只要你为你传入的NSURLRequest设置适当的缓存策略。我可能会遗漏一些东西,但我不确定是什么缓存政策我会设定。这一切似乎都是为了记忆而改变图像,而不是为了记忆而清除。

我也认为谎言触及了这个issue中的同一个问题,除非设置了totalCostLimit,否则缓存不会自我清理。虽然我不相信在这种情况下使用模拟器与模拟内存警告配对,但症状是相同的。

感谢您帮助调试此

修改

添加建议代码后的分析更新

enter image description here

2 个答案:

答案 0 :(得分:11)

AFNetworking的图像缓存使用NSCache,它可以清除系统内存压力,但不会清除单个应用程序的内存警告。

为了解决这个问题,2.x branch of AFNetworking添加了以下代码:

[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidReceiveMemoryWarningNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * __unused notification) {
    [_af_defaultImageCache removeAllObjects];
}];

将清除内存警告缓存。

如果您仍在the 1.x branch,则不会包含此代码(更新:已在this commit中添加),这可能会导致您看到的行为。您可以更新到2.x,或者只是将此代码添加到您的应用中。

  

只要您为传入的NSURLRequest设置了适当的缓存策略,它应该足够并且完全自我维护

请注意,NSCache和NSURLCache是​​两个非常不同的类。 NSCache是​​您在问题中寻找的那个。另一方面,NSURLCache仅缓存对URL加载请求的响应。

UIImageView + AFNetworking使用NSCache存储UIImage对象。 NSURLCache存储NSData对象,并且从此缓存中检索对象通常对于在UITableView或UICollectionView中显示图像的图像繁重的应用程序而言不够高。

最后,您可能希望将您的实现与使用SDWebImage项目的实现进行比较。 SDWebImage提供磁盘和内存缓存,比AFNetworking的UIImageView + AFNetworking更能控制细节。

答案 1 :(得分:0)

AFNetworking现在将此修复程序提交到其1.x分支和2.x分支。不再需要升级到AFNetworking 2.x来解决问题。您不再需要编辑UIImageView + AFNetworking.m。

这是提交:https://github.com/AFNetworking/AFNetworking/commit/66a29256ed0724e8c9033ee4847e1f09f800ce42#diff-d41d8cd98f00b204e9800998ecf8427e

您可以在此处查看该文件的固定版本: https://github.com/AFNetworking/AFNetworking/blob/1.x/AFNetworking/UIImageView%2BAFNetworking.m