将UIImage保存到核心数据正在耗尽RAM。嘿嘿?

时间:2010-08-31 01:46:02

标签: iphone core-data

这是一个小背景:

我在Core Data中存储了相当大的图像(900x1200像素)。它们来自UIImagePickerView,我将它们裁剪并调整为合理的大小。

我正在使用一个非常标准的值转换器来转换UIImage和NSData(并返回。)

该程序有效,但最终会收到内存警告,然后终止。

如果删除将图像写入Core Data的行,则问题就会消失(但我需要存储这些图像!)

当我运行Instruments时,“分配”会在图像选择器返回全分辨率图像时显示预期的峰值,并将其调整大小。转换完成后,我从5转到约22兆,然后回到5。

分配从未显示出任何增长。

我有一个大约200字节的泄漏,我几乎是积极的无关,但我在完全披露中提到它。

现在,当我使用Memory Monitor仪器时,我发现每次保存其中一个图像时,我的应用程序的“真实内存”增长了5兆。

所以,非常感谢任何帮助(或想法)!

为什么分配没有显示出这种增长,但内存监视器呢?这是一个线索吗?

起初我以为是因为我的价值转换器使用的自动释放池可能没有耗尽,但后来我意识到这是我读取数据时,而不是写入数据。

这是相关的代码。如果您对我如何调试这个有任何想法,请告诉我!

-Pete

这是我的价值转换器: 首先是接口声明:

@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];  

2 个答案:

答案 0 :(得分:4)

它无法解决这个谜团,但可以解决您的问题(除非您有某种理由绝对要求以这种方式使用Core Data),但您不应该使用Core Data。它只是不是为了存储如此庞大的二进制数据块而设计的。而是在Core Data中存储对数据(即文件名或URL)的引用,并使用NSData的{​​{1}}和dataWithContentsOfFile

答案 1 :(得分:2)

问题在于Core Data为了性能而缓存了很多。我应该早些时候猜到这一点,因为我已经编写了类似的通用数据存储算法。它也解释了为什么我没有看到它被分配为我的记忆。将保存消息发送到托管对象上下文时,写入的数据将被缓存。

您可以使用NSManagedObjectContext消息“RefreshObject:mergeChanges:”将NSManagedObjects标记为“脏”(故障)。在发送保存消息的上下文后,直接对该对象执行此操作。

通过使用“NO”作为第二个参数,您说,“您需要返回磁盘才能获得它。”

poof ,解决了我的内存使用问题。

当修复是一行代码时,你不喜欢它吗?

-Pete