【问题标题】:Downloading images using AFNetworking - Memory won't release after poping ViewController using ARC使用 AFNetworking 下载图像 - 使用 ARC 弹出 ViewController 后内存不会释放
【发布时间】:2013-09-14 20:38:10
【问题描述】:

我的应用遇到了一些奇怪的内存问题。 经过一些调试后,我已将问题隔离到具有一个视图控制器的新项目中。 所以现在我的测试应用程序包含一个UINavigationController 连接到一个ViewController 并带有一个按钮来推动下一个ViewController

#import "ViewController.h"
#import "AFNetworking.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    for(int i=0;i<100;i++)
    {
        NSString *rightImageUrl = [NSString stringWithFormat:@"%@/%@-iphone%@.png",ImagesURL,[NSString stringWithFormat:@"%d",i],@"4"];
        UIImageView *rightImageView = [[UIImageView alloc]initWithFrame:CGRectMake(6, 50*i , 139, 200)];
    [rightImageView setImageWithURL:[NSURL URLWithString:rightImageUrl]];
        [self.view addSubview:rightImageView];
    }    
}

以上是我现在测试应用程序中的所有代码。

根据 Instruments,上面需要 X 内存量(10mb,20mb .. 取决于循环的数量)问题是当我弹出 ViewController 时,从上面分配的内存不会被释放.

我尝试使用 @autoreleasepool 将代码包装在 for 循环中,但效果不大。

请指教

【问题讨论】:

  • 这如何编译? setImageWithURL 是 IKImageView 方法,而不是 UIImageView 方法。
  • @rdelmar 这是一个UIImageView+AFNetworking 方法。
  • @Rob,哦,好吧,错过了那个 afnetworking 标签。

标签: ios objective-c memory-management automatic-ref-counting afnetworking


【解决方案1】:

UIImageView+AFNetworking 类别使用 NSCache 子类缓存图像,这意味着它将使您无需重新检索图像(这非常有用,如果您返回此视图,可以避免性能/网络影响控制器)。这个缓存会在内存压力下自动清除,所以你可能不需要担心它(只要你确信你的视图控制器本身被正确地释放并且不会受到一些强引用循环的影响,或者之类的)。

如果您真的想清除此缓存,则必须对UIImageView+AFNetworking 代码进行一些更改以公开AFImageCache 类。您可能希望使其成为一个适当的单例类(因为现有的实现依赖于UIImageView+AFNetworking 来控制af_sharedImageCache),然后您可以使用NSCache 方法removeAllObjects 清除缓存。

您可能必须权衡通过这种努力的利弊。例如,它有缓存真的有问题吗(因为缓存会在内存压力下自动清除)?如果您不必要地清空缓存,您的应用程序将无法享受缓存带来的性能优势。如果你 fork AFNetworking 并且作者没有将它合并回代码的主分支,那么这对你未来的 AFNetworking 更新有何影响?

如果您决定要控制缓存,您还可以考虑将AFNetworking+UIImageView 从您的项目中排除,并考虑使用不同的UIImageView 类别来提供对缓存的一些控制。例如,我相信SDWebImage 会公开缓存,因此您可以根据需要清除它(它还提供其他优势)。可能有很多UIImageView 类别比 AFNetworking 的更强大。


顺便说一句,我们通常会使用延迟加载图像,而不是预先加载所有 100 张图像,只设置那些在任何给定时刻可见的图像视图的 image 属性,并在它们滚动时加载其他图像进入视野。 UIImageView+AFNetworking 类别处理图像的优雅异步加载,以确保应用程序的响应能力。如果您预先加载 100 张图片,它可能会对您的应用可能需要执行的其他网络操作(如果有的话)产生不利影响。

【讨论】:

  • 我在使用 NSCache 时不知道内存管理。内容丰富的答案。谢谢!
猜你喜欢
  • 2013-07-01
  • 2013-08-25
  • 2013-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多