Мое приложение считывает и изменяет размеры изображений, загружаемых из Интернета;и, к сожалению, я не могу контролировать создание этих образов.
Недавно у меня произошел сбой, который я не знаю, как лучше всего справиться.В этом случае изображение было поврежденным GIF-файлом.Он не был сильно поврежден, но сообщал, что размер разрешения (высота х ширина) был неточным.Предполагалось, что это изображение размером 400x600, но оно сообщало что-то вроде 1111x999.
Сбой фрагмента кода:
- (void) saveRawImageRefToDisk:(CGImageRef)image withUUID:(NSString *)uuid andType:(NSString *)type {
if (!uuid || !type) {
return;
}
NSDictionary *imageDestinationWriteOptions = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:1], (id)kCGImagePropertyOrientation,
(id)kCFBooleanFalse, (id)kCGImagePropertyHasAlpha,
[NSNumber numberWithInt:1.0], kCGImageDestinationLossyCompressionQuality,
nil];
CGImageDestinationRef imageDestination = CGImageDestinationCreateWithURL((CFURLRef)[NSURL fileURLWithPath:[self getRawImagePathForUUID:uuid]], (CFStringRef)type, 1, nil);
if (imageDestination) {
CGImageDestinationAddImage(imageDestination, image, (CFDictionaryRef)imageDestinationWriteOptions);
CGImageDestinationFinalize(imageDestination); //<--- EXC_BAD_ACCESS in here
CFRelease(imageDestination);
}
}
Фрагмент журнала сбоя:
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x06980000
Crashed Thread: 8
Thread 8 name: Dispatch queue: com.apple.root.default-priority
Thread 8 Crashed:
0 libsystem_c.dylib 0x348cf6a4 memcpy$VARIANT$CortexA9 + 212
1 CoreGraphics 0x366de30c CGAccessSessionGetBytes + 112
2 ImageIO 0x32941b04 GenerateFromRGBImageWu + 256
3 ImageIO 0x329432aa _CGImagePluginWriteGIF + 3390
4 ImageIO 0x32932b3a CGImageDestinationFinalize + 118
Изображение, о котором идет речь, представляло собой GIF, поэтому в моем методе был установлен тип @ "com.compuserve.gif" .Насколько я могу судить, CGImageDestinationRef imageDestination был допустимым объектом.
Часть логики моего приложения - сохранять изображения в том же формате, в каком они читаются.Так что в этом случае я изменял размеры и выписывал GIF.
Я пытался заставить записать CGImageRef в виде PNG, и, что интересно, приложение не вылетало.Он записал PNG (который был недействителен - просто пустое черное изображение), но не вылетел.Но я не имею ни малейшего представления в обычном порядке исполнения, чтобы знать, что я должен написать GIF как PNG.
У кого-нибудь есть какие-либо идеи относительно того, как я могу справиться или перехватить это условие?Я очень ценю любые предложения, так как это беспокоит меня по поводу стабильности приложения.Или это просто «отчет как радар для Apple»?
Изменения и дополнительный код:
Вся эта обработка происходит в NSOperationQueueа не в основном потоке
Изображение, о котором идет речь, доступно по адресу http://dribbble.com/system/users/1409/screenshots/182540/htg-logo-tiny.gif?1306878218
Вот функция, где я создаю CGImageRef:
- (CGImageRef) createIpadSizedImageRefFromImageSource:(CGImageSourceRef)imageSource withSourceSizeOf(CGSize)imageSourceSize {
NSDictionary *imageCreationOptions = [NSDictionary dictionaryWithObjectsAndKeys:
(id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailWithTransform,
(id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailFromImageIfAbsent,
[NSNumber numberWithInt:1024], kCGImageSourceThumbnailMaxPixelSize,
(id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailFromImageAlways,
nil];
CGImageRef image = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, (CFDictionaryRef)imageCreationOptions);
if (!image) {
return nil;
} else {
[(id) image autorelease];
return image;
}
}
иCGImageSourceRef создается из пути к файлу:
- (CGImageSourceRef) createImageSourceFromURL:(NSURL *)imageLocationOnDisk {
CGImageSourceRef imageSource = CGImageSourceCreateWithURL((CFURLRef)imageLocationOnDisk, NULL);
if (!imageSource) {
DebugLog(@"Issue creating image source for image at: %@", imageLocationOnDisk);
return nil;
} else {
[(id) imageSource autorelease];
return imageSource;
}
}