Here's a little background:
I'm storing pretty big images (900x1200 pixels) in Core Data. These are coming from the UIImagePickerView, and I crop and resize them into this reasonable size.
I'm using a pretty standard value transformer to convert between the UIImage and NSData (and back.)
The program works, but it ends up getting memory warnings and then gets terminated.
If I remove the line that writes out the image to Core Data, the problem goes away (but I need those images stored!)
When I run Instruments, "Allocations" shows an expected spike when the image picker returns the full resolution image and I resize it down. I go from 5 to about 22 megs and back to 5 after the transformation is complete.
Allocations never shows any more growth.
I DO have a roughly 200 byte leak that I'm almost positive is unrelated, but I mention it in full disclosure.
Now, when I use the Memory Monitor instrument, I see that my app's "Real Memory" is growing by 5 megs every time I save one of these images.
So, any help (or ideas) would be greatly appreciated!
Why does Allocations not show this growth, but Memory Monitor does? Is this a clue?
At first I thought it was because my value transformer was using an auto release pool that might not be getting drained, but then I realized that was when I READ the data, not write it.
Here's the pertinent code. Please let me know if you have ANY ideas on how I can debug this!
-Pete
Here's my value transformer: First the interface declaration:
@interface ImageToDataTransformer : NSValueTransformer { }
@end
And now the implementation:
@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];
}
Here's the code where I write it out:
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];