Philippe Sabourin
Philippe Sabourin

Reputation: 8075

What could cause [UIImage imageWithData] to crash when it comes back

I have this code in one of my NSManagedObjects:

if (self.tempImageStorage) {
    return self.tempImageStorage;
} else if(self.imageData) {
    NSLog(@"%@ %d",self.imageData, self.imageData.length);
    self.tempImageStorage = [UIImage imageWithData:self.imageData];
    return self.tempImageStorage;
}

Occasionally, usually when I'm flipping through the images quickly, it will come back with an EXC_BAD_ACCESS on the 5th line (UIImage imageWithData line), and I can't po (printobject) self in the console, so I assume that the NSMananagedObject itself has been deallocated. What doesn't make sense is that it was able to reference self for the 2 ifs, and I even log the image data and its length just fine right before it.

How could the NSManagedObject be deallocated in during that period since this is all happening on the same thread (and it's the main thread)?

PS: I have Zombies enabled but it still doesn't let me po self.

Code that sets the image data:

- (void) processRequest:(ASIHTTPRequest *) request
{
    UIImage * orig = [UIImage imageWithData:[request responseData]];
    CGSize targetSize = isPad()?CGSizeMake(446,150):CGSizeMake(320, 108);
    CGRect fourPanelSize = CGRectMake(0, 0, 1000, 336);
    CGImageRef imageRef = CGImageCreateWithImageInRect([orig CGImage], fourPanelSize);
    CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);
    CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef);

    if (bitmapInfo == kCGImageAlphaNone || bitmapInfo == kCGImageAlphaLast) {
        bitmapInfo = kCGImageAlphaPremultipliedLast;
    }

    CGContextRef bitmap;
    bitmap = CGBitmapContextCreate(NULL, targetSize.width, targetSize.height, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);    

    CGContextDrawImage(bitmap, CGRectMake(1, 1, targetSize.width-2, targetSize.height-2), imageRef);
    CGImageRef ref = CGBitmapContextCreateImage(bitmap);
    UIImage* newImage = [UIImage imageWithCGImage:ref];

    CGContextRelease(bitmap);
    CGImageRelease(ref);

    NSData * thumbData = UIImagePNGRepresentation(newImage);
    NSData * imageData = UIImagePNGRepresentation(orig);

    //Post notification on main thread since it will be updating the UI
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        self.tempImageThumbStorage = newImage;
        self.imageThumbnailData = thumbData;
        self.tempImageStorage = orig;
        self.imageData = imageData;

        [(AppDelegate*)[UIApplication sharedApplication].delegate saveContext];

        NSMutableDictionary * userInfo = [[NSMutableDictionary alloc] initWithCapacity:1];
        [userInfo setObject:[NSNumber numberWithBool:YES] forKey:@"status"];
        [userInfo setObject:self forKey:@"comic"];

        [[NSNotificationCenter defaultCenter] postNotificationName:PCRLoadMediahNotification object:self userInfo:userInfo];
        strongSelf = nil;
    }];

}

Upvotes: 2

Views: 1188

Answers (2)

Jevgenij Kononov
Jevgenij Kononov

Reputation: 1239

I have faced with the same problem when I was parsing image from internet. So then when I was recreating image in app I got crash like this:

UIImage *img = [UIImage imageWithData:imgData] -> EXC_BAD_ACCESS (code =2 0x...)

So my problem was that I have not synchronized this action with main app thread, that is why my app was crashing. The strangest part: that simulators works perfectly while real device crashes.

To make synchronization I have added this action:

  • (void) GetImage:(NSData*)imgData number:(int)i {

    [[NSOperationQueue mainQueue] addOperationWithBlock:^{ @synchronized (imgData) { //UIImage* img2=[UIImage imageWithData:imgData]; NSLog(@"picture number %d",i); uiimager_array[i] =[UIImage imageWithData:imgData]; } }];

}

After that I am calling in my loop this void function which is now not leads app to crash. Hops that helps

Upvotes: 0

Philippe Sabourin
Philippe Sabourin

Reputation: 8075

Turns out I was saving the context too often which was causing the imageData not to be saved to disk properly, and causing the exception.

Upvotes: 2

Related Questions