I'm having a problem when I try to save an UIImage as a PNG file by using GCD. Here's what am I writing :
NSString *fileName = [[NSString stringWithFormat:@"%@.png",url] substringFromIndex:5];
dispatch_queue_t queue = dispatch_queue_create("screenshotQueue", NULL);
dispatch_async(queue, ^{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:fileName];
[fileManager createFileAtPath:filePath contents:UIImagePNGRepresentation(image) attributes:nil];
});
dispatch_release(queue);
It's working a first time but the other times I have nothing created. And this %@.png is weird because my only file created is not recognize by Finder. I have to add .png extension to the file (so filename.png.png) and I can open it then.
It looks like a race condition. You are releasing the queue immediately after dispatching the block to it. Any blocks that have not been executed before the call to
dispatch_release
will be cancelled, and there is a chance that GCD is not done preparing itself before you calldispatch_release
.Since you're only ever submitting a single block to the screenshotQueue, you are better off using one of the global system queues. That way, you don't have to deal with managing the queue's lifecycle.
This will probably give you more consistent results:
I'm not sure about the PNG file type problem. It sounds like Finder doesn't know the file's type. You can use this command to find the type Spotlight has in its index:
It should report back something like this:
I typically use
[NSData writeToFile:atomically:]
for saving bytes to disk, and it usually handles the details properly. It might be overkill, but you could also use Image I/O to be doubly sure:I do all of my image loading/saving/thumbnailing with Image I/O now. It's really fast. Of course, make sure you add ImageIO.framework to your project if you decide to use it.