How to avoid malloc while using CGImageDestination

2019-02-26 02:11发布

问题:

I am trying to programmatically create GIF in iOS, using the following stack's question:

Create and and export an animated gif via iOS?

My code looks like this:

 // File Parameters
const void *keys[] =   { kCGImagePropertyGIFLoopCount };
const void *values[] = { (CFNumberRef) 0 };

CFDictionaryRef params          = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
const void *keys2[] =   { kCGImagePropertyGIFDictionary };
const void *values2[] = { (CFDictionaryRef) params  };

CFDictionaryRef fileProperties  = CFDictionaryCreate(NULL, keys2 , values2, 1, NULL, NULL);

// URL to the documents directory
NSURL *documentsDirectoryURL  = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:nil];
NSURL *fileURL                = [documentsDirectoryURL URLByAppendingPathComponent:fileName];

// Object that writes GIF to the specified URL
CGImageDestinationRef destination = CGImageDestinationCreateWithURL((__bridge CFURLRef)fileURL, kUTTypeGIF, [arrayOfAllFrames count], NULL);
CGImageDestinationSetProperties(destination, fileProperties);

for (NSUInteger i = 0; i < [arrayOfAllFrames count]; i++) {
    @autoreleasepool {
        float delayTime = [[gifFramesDuration objectAtIndex:i] floatValue]; 
        NSDictionary *frameProperties = @{
                                          (__bridge id)kCGImagePropertyGIFDictionary: @{
                                                  (__bridge id)kCGImagePropertyGIFDelayTime: [NSNumber numberWithFloat:delayTime] // a float (not double!) in seconds, rounded to centiseconds in the GIF data
                                                  }
                                          };

        UIImage *myImage = [arrayOfAllFrames objectAtIndex:i];
        CGImageDestinationAddImage(destination, myImage.CGImage, (__bridge CFDictionaryRef)frameProperties);
    }
}
if (!CGImageDestinationFinalize(destination)) {
    NSLog(@"failed to finalize image destination");
}
CFRelease(destination);
CFRelease(fileProperties);
CFRelease(params);

However once I try to add around 240 frames to the GIF file, debugger throws the following error once the CGImageDestinationFinalize gets called:

(923,0xb0115000) malloc: *** error for object 0xd1e7204: incorrect checksum for freed object - object was probably modified after being freed.

Could you please provide me with some workaround, or with a suggestion on how to avoid malloc?

回答1:

First of all, try debugging your app using Instruments. You probably will notice that the problem is caused by the method: Generatefromrgbimagewu

I have been wondering whether the cause was in my threads implementation, but it turns out, that once you have that kind of error, you should focus on resizing the Image.

Once the image had been resized, the code published above, will generate your own GIF.