Reputation: 9887
I got this symbolicated stack trace from a crash report from my iPad app (excerpt):
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x00000000, 0x00000000
Crashed Thread: 0
0 ImageIO 0x34528eb4 _CGImagePluginIdentifyPNG + 0
1 ImageIO 0x34528d90 _CGImageSourceBindToPlugin + 368
2 ImageIO 0x34528bda CGImageSourceGetCount + 26
3 UIKit 0x341b8f66 _UIImageRefAtPath + 366
4 UIKit 0x342650ce -[UIImage initWithContentsOfFile:] + 50
5 UIKit 0x342b0314 +[UIImage imageWithContentsOfFile:] + 28
6 DesignScene 0x00013a2a -[LTImageCache fetchImageforURL:] (LTImageCache.m:37)
…
Here are the contents of -[LTImageCache fetchImageforURL:]
:
- (UIImage *)fetchImageforURL:(NSString *)theUrl {
NSString *key = theUrl.md5Hash;
return [UIImage imageWithContentsOfFile:[self filenameForKey:key]];
}
And the contents of -[LTImageCache filenameForKey:]
:
- (NSString *) filenameForKey:(NSString *) key {
return [_cacheDir stringByAppendingPathComponent:key];
}
The _cacheDir
ivar is created and retained in -init
. So the question is, what caused this crash? Is the problem that:
-[LTImageCache filenameForKey:]
needs to be retained (it's autoreleased)+[UIImage imageWithContentsOfFile:]
claims to return nil
if the image is unrecognizable)I would think that an autoreleased value would be fine. An in truth, this code has been working fine for months, and this method is called 100s of times in a session. This is a rare crash under very specific circumstances (the app left loaded overnight, crash upon unlocking the iPad in the morning).
What's causing this crash?
Upvotes: 1
Views: 818
Reputation: 3358
I'm guessing but it looks like a bogus image file. Is this in your app bundle or do you download it?
I don't think it has anything to do with memory mgt.
To test you could try using ImageIO to open the file yourself.
CGImageSourceRef imageSource = CGImageSourceCreateWithURL((CFURLRef)self.url, NULL);
if(NULL != imageSource) {
size_t imageCount = CGImageSourceGetCount(imageSource);
if(imageCount > 0) {
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], kCGImageSourceCreateThumbnailFromImageIfAbsent,
[NSNumber numberWithInteger:maxSize], kCGImageSourceThumbnailMaxPixelSize, nil];
CGImageRef thumbImage = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, (CFDictionaryRef)options);
self.image = [UIImage imageWithCGImage:thumbImage scale:scale orientation:imageOrientation];
CGImageRelease(thumbImage);
CFRelease(imageSource);
[pool drain];
}
} else {
NSLog(@"Unable to open image %@", self.url);
}
and then try to find the image count.
Using maxSize
and getting a thumbnail will ensure you don't load a 5 mega-pixel image to put into a 100x100 tile on your UI.
scale
is the window's scale (will be 2 for iPhone 4 and 1 for everything else).
To find the orientation you need to use the CGImageSourceCopyPropertiesAtIndex
function and then the kCGImagePropertyOrientation
key to get the orientation of the particular image.
Upvotes: 1