【发布时间】:2014-03-25 13:28:51
【问题描述】:
幸运的是,我知道我的内存压力问题来自哪里,并且我尝试了许多技术,例如将块包装在 @autorelease 块中并将对象设置为 nil,但仍然没有成功。
很抱歉在这里倾倒了太多代码,我试图将其缩减为基本要素。这是下载和保存图片的代码:
NSMuttableArray *photosDownOps = [NSMuttableArray array];
NSURL *URL = [...];
NSURLRequest *request = [...];
AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request];
op.responseSerializer = [AFImageResponseSerializer serializer];
[op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
dispatch_queue_t amBgSyncQueue = dispatch_queue_create("writetoFileThread", NULL);
dispatch_async(amBgSyncQueue, ^{
[self savePhotoToFile:(UIImage *)responseObject usingFileName:photo.id];
});
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if ([error code] != NSURLErrorCancelled)
NSLog(@"Error occured downloading photos: %@", error);
}];
[photosDownOps addObject:op];
NSArray *photosDownloadOperations = [AFURLConnectionOperation batchOfRequestOperations:photosDownloadOperatons
progressBlock:^(NSUInteger nof, NSUInteger tno) {
} completionBlock:^(NSArray *operations) {
NSLog(@"all photo downloads completed");
}];
[self.photosDownloadQueue addOperations:photosDownloadOperations waitUntilFinished:NO];
+ (void) savePhotoToFile:(UIImage *)imageToSave usingFileName:(NSNumber *)photoID{
@autoreleasepool {
NSData * binaryImageData = UIImageJPEGRepresentation(imageToSave, 0.6);
NSString *filePath = [Utilities fullPathForPhoto:photoID];
[binaryImageData writeToFile:filePath atomically:YES];
binaryImageData = nil;
imageToSave = nil;
}
}
这种情况虽然只发生在我测试过的 iPhone 4s 设备上,但不会发生在 iPhone 5 机型上。
【问题讨论】:
-
您是否使用 Instruments 测量过代码的内存使用情况?这将告诉您分配来自何处,按对象类型分组以及每个实例的分配历史。您首先需要确定造成所有内存压力的对象是哪些对象,然后追踪这些对象的来源并了解它们的所有用途以了解如何继续。
-
您要获取的图像的分辨率是多少,显示所需的最大分辨率是多少?您是否有机会缩小图像以减少整体数据?在平均应用会话中,您通常处理多少张图片?
-
我可以看到整个图像首先下载到缓存中,然后在成功块中返回给您。如果图像大小相当大,这可能是内存峰值的原因。您应该编写自己的操作,在里面发出请求,在 NSUrlConnectionDelegate 的 didReceiveData 方法中,您接收块中的响应数据,使用 NSOutputStream 将该数据写入所需的文件位置。我想这会解决你的问题。
-
@bneely 的罪魁祸首是 VM:CG rasta 数据和 VM:ImageIO_Data,每个的总字节数为 130MB,整个应用程序的总字节数为 1.2GB。我以 480x640 的分辨率和每张
-
你能在把它们当作 UIImage 之前将它们写入磁盘吗?获取图像后是否立即显示/使用?您可以将它们作为不透明的 NSData 处理并以这种方式将它们写入磁盘。然后你会避免不必要的 UIImage 缓存。当您需要给定图像时,从磁盘加载它,然后调用 UIImageJPEGRepresentation()。换句话说,将 UIImage 工作推迟到最后一刻。
标签: ios iphone memory-leaks out-of-memory memory-pressure