Fork me on GitHub

saveImageWithData

- (void)saveImageWithData:(NSData*)jpeg andDictionary:(NSDictionary*)dicRef andName:(NSString*)name
{
    [self setCapturedImageName:name];

    CGImageSourceRef  source ;

    // Notice here how I use __bridge
    source = CGImageSourceCreateWithData((__bridge CFDataRef)jpeg, NULL);

    CFStringRef UTI = CGImageSourceGetType(source); 

    NSMutableData *dest_data = [NSMutableData data];

    // And here I use it again
    CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)dest_data,UTI,1,NULL);

    CGImageDestinationAddImageFromSource(destination,source,0, (__bridge CFDictionaryRef) dicRef);

    BOOL success = NO;
    success = CGImageDestinationFinalize(destination);

    if(!success) {
        NSLog(@"***Could not create data from image destination ***");
    }

    // This only saves to the disk
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
    NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:@"ARPictures"];

    NSError *error;
    if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
        [[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:&error]; //Create folder

    NSString *fullPath = [dataPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.jpg", name]]; //add our image to the path

    [dest_data writeToFile:fullPath atomically:YES];


    self.img = [[UIImage alloc] initWithData:dest_data]; 
    self.capturedImageData = [[NSData alloc] initWithData:dest_data];

    //This is what im not sure if i should use
    CFRelease(destination);
    CFRelease(source);

}

My question is very simple, I would like to know if the method "CGImageSourceCreateWithData"creates a new object copying the data I provide so that that I have to release it when I don't need it anymore, or if it just creates a reference to the data I already have so that if I release it I will lose this data (and possibly have bad access errors).

The issue is related to using (__bridge CFDataRef) as the source data. Which let's me use Core Foundation objects as toll-free in ARC mode.

Consider the following function (or method, not sure how it's called):

 

 

You are doing it correctly. It does not actually matter whether these routines make copies or not. What matters is that you CFRelease what you "Create" (or "Copy"). Everything here looks correct.__bridge is appropriate when passing parameters because you're not actually transferring the object from CF to Cocoa or vice versa. You're just temporarily "bridging" (casting) it.

 

Oh i see, so basically what i create i should always release right? I was a bit confused because i wanted to optimize this code, and was considering the possibility of using the cocoa objects directly bridging them so that I dont have these extra 2 copies. Becase right now i have the Original data (the jpeg data that comes in), the source and the destination and even tho i release the last 2 the process seems to consume a lot of memory. Can this be done? btw thanks for ur fast reply – Luis Oscar Feb 28 at 2:44


You need to balance a CFRelease with any method that includes Create or Copy in the name. As for the rest, I'm not certain why you're using Core Graphics here. You can convert JPEG data into a UIImage with imageWithData:. Are you doing something more complex in there? – Rob Napier Feb 28 at 3:32


Yeah, I am modifying the metadata from the image by adding some extra information, so i thought that this was the only way to modify that data. – Luis Oscar Feb 28 at 3:41


ok; yes, this is the way to do that. So when you say "seems to consume a lot of memory," how are you checking this? Remember, when you free memory, it doesn't immediately go back to the OS. You'll actually hold onto it in case you need it again, and the OS will only really take it back if it needs it. I recommend the Instruments Allocation tool for tracing memory usage. Activity Monitor can sometimes send you down the wrong path. – Rob Napier Feb 28 at 3:44


Its just that my program crashes haha so i thought it would be the memory cuz no error is displayed and it just exists, I will try the allocation tool, thanks. – Luis Oscar Feb 28 at 3:54

posted on 2012-05-04 15:52  pengyingh  阅读(965)  评论(0)    收藏  举报

导航