我的应用程序遇到了一些奇怪的内存问题。
经过一些调试后,我已经将问题隔离到一个带有一个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];
}
}
以上是我现在在测试应用中的所有代码。
根据仪器,上面需要X量的内存(10mb,20mb ......取决于循环的数量)问题是当我弹出{{1时,上面分配的内存不会被释放}}
我尝试用@autoreleasepool将代码包装在for循环中,但这并没有做太多。
请告知
答案 0 :(得分:2)
UIImageView+AFNetworking
类别使用NSCache
子类缓存图像,这意味着它将使您无需重新检索图像(这非常有用,如果您避免性能/网络影响返回此视图控制器)。此缓存会在内存压力下自动清除,因此您可能不必担心它(只要您确信您的视图控制器本身已正确解除分配并且不会受到某些强大的参考周期或之类的。)
如果您确实要清除此缓存,则必须对UIImageView+AFNetworking
代码进行一些更改以公开AFImageCache
类。你可能想让它成为一个合适的单例类(因为现有的实现依赖于UIImageView+AFNetworking
来控制af_sharedImageCache
),然后你可以使用NSCache
方法{{清除缓存1}}。
你可能不得不权衡经历这种努力的利弊。例如,它是否真的存在一个问题,它有一个缓存(因为无论如何,该缓存会在内存压力下自动清除)?如果您不必要地清空缓存,您的应用程序将无法享受缓存的性能优势。如果您分叉AFNetworking并且作者没有将其合并回代码的主分支,那么您将在何处留下未来的AFNetworking更新?
如果您决定要控制缓存,可以考虑从项目中排除removeAllObjects
,并考虑使用另一个AFNetworking+UIImageView
类别来控制缓存。例如,我相信SDWebImage会公开缓存,因此您可以根据需要清除缓存(它也提供其他优势)。可能有很多UIImageView
类别比AFNetworking更强大。
顺便说一句,我们不是预先加载所有100张图片,而是经常使用延迟加载图片,只设置在任何给定时刻可见的图像视图的UIImageView
属性,并将其他图像加载为他们滚动到视图中。 image
类别处理图像的正常异步加载,以确保应用程序响应。如果您预先加载了100张图片,则可能会对您的应用可能需要执行的其他网络操作产生负面影响(如果有)。