1

我的应用程序遇到了一些奇怪的内存问题。经过一些调试后,我用一个 View 控制器将问题隔离到了一个新项目中。所以现在我的测试应用程序包含一个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 循环中,但这并没有起到多大作用。

请指教

4

1 回答 1

2

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 张图像,它可能会对您的应用可能需要执行的其他网络操作(如果有)产生不利影响。

于 2013-09-11T00:57:18.947 回答