这里有一些背景:
我在 Core Data 中存储相当大的图像(900x1200 像素)。这些来自 UIImagePickerView,我将它们裁剪并调整为合理的大小。
我正在使用一个相当标准的值转换器在 UIImage 和 NSData 之间进行转换(以及返回。)
该程序可以运行,但最终会收到内存警告,然后被终止。
如果我删除将图像写入核心数据的行,问题就会消失(但我需要存储这些图像!)
当我运行 Instruments 时,当图像选择器返回全分辨率图像并且我将其缩小时,“分配”会显示预期的峰值。我从 5 变为大约 22 兆,转换完成后又回到 5。
分配再也没有显示出任何增长。
我确实有大约 200 字节的泄漏,我几乎肯定这是无关的,但我完全披露了它。
现在,当我使用内存监视器工具时,我发现每次保存其中一张图像时,我的应用程序的“真实内存”都会增加 5 兆。
因此,任何帮助(或想法)将不胜感激!
为什么分配没有显示这种增长,但内存监视器却显示?这是一个线索吗?
起初我以为这是因为我的值转换器使用了一个可能不会被耗尽的自动释放池,但后来我意识到那是当我读取数据而不是写入数据时。
这是相关代码。如果您对如何调试它有任何想法,请告诉我!
-皮特
这是我的值转换器: 首先是接口(interface)声明:
@interface ImageToDataTransformer : NSValueTransformer { }
@end
现在实现:
@implementation ImageToDataTransformer
+ (BOOL)allowsReverseTransformation {
return YES;
}
+ (Class)transformedValueClass {
return [NSData class];
}
- (id)transformedValue:(id)value {
NSData *data = UIImagePNGRepresentation(value);
return data;
}
- (id)reverseTransformedValue:(id)value {
UIImage *uiImage = [[UIImage alloc] initWithData:value];
return [uiImage autorelease];
}
这是我写出来的代码:
FieldCollectorAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSError *error;
NSManagedObject *theFieldObject=nil;
// Populate the bare necessities
theFieldObject = [NSEntityDescription insertNewObjectForEntityForName:@"FieldObject"
inManagedObjectContext:context];
NSManagedObject *theImageObject =[NSEntityDescription insertNewObjectForEntityForName:@"ImageObject" inManagedObjectContext:context];
// Let's link up the two
[theImageObject setValue:theFieldObject forKey:@"fieldObject"];
[theFieldObject setValue:theImageObject forKey:@"photo"];
[theFieldObject setValue:image forKeyPath:@"photo.Photo"];
// Save the context
[context save:&error];
最佳答案
它并不能解决这个谜团,但可能会解决您的问题(除非您有某种原因绝对需要以这种方式使用 Core Data),但您不应该使用 Core Data。它只是不是为了存储如此大的二进制数据 block 而设计的。而是在 Core Data 中存储对数据的引用(即文件名或 URL),并使用 NSData
的 dataWithContentsOfFile
和 writeToFile
。
关于iphone - 将 UIImage 保存到核心数据会耗尽 RAM。什么啊嘿?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3605504/