-2

I have a problem with some image-scaling code that throws an exception in iOS5 but works in 6 and 7.

I need to support users running 5 so I am trying to code a try-catch which will call some special iOS5 code when the exception occurs.

The exception (EXC_BAD_ACCESS) seems to happen in Apple code, and the exception handler in my code does not handle the error but the app just immediately crashes.

So, can anyone suggest a more robust way to trying to catch the exception, or can anyone shed any light on a better way of scaling images? (remembering that this is for iOS5)

My main image-scaling function (containing the exception catcher that does not work):

+ (UIImage *)imageWithImage:(UIImage *)image scaledToMax:(int)maxDimension {

    // Get a copy of the image where the new image has a maximum height or width as specified by maxDimension

    float scaleFactor;

    if (image.size.width<=maxDimension && image.size.height<=maxDimension)
    {
        return image;
    }

    if (image.size.width>image.size.height)
    {
        scaleFactor = maxDimension / image.size.width;

    } else {

        scaleFactor = maxDimension / image.size.height;

    }

    float newWidth = roundf(image.size.width * scaleFactor);
    float newHeight = roundf(image.size.height * scaleFactor);

    CGSize newSize = CGSizeMake(newWidth, newHeight);

    UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);

    NSLog(@"HPSImageHelper imageWithImage point a %f %f", newSize.width, newSize.height);

    UIImage *newImage;

    @try {

        [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];

        NSLog(@"HPSImageHelper imageWithImage point b");
        newImage = UIGraphicsGetImageFromCurrentImageContext();
        NSLog(@"HPSImageHelper imageWithImage point c");
        UIGraphicsEndImageContext();

    }
    @catch (NSException * e) {

        NSLog(@"HPSImageHelper imageWithImage point d");

        newImage = [image scaleToSize:newSize];

        NSLog(@"HPSImageHelper imageWithImage point e");
    }

    NSLog(@"HPSImageHelper imageWithImage point f");

    return newImage;


}

enter image description here

Gabriele Petronella
  • 106,943
  • 21
  • 217
  • 235
Journeyman
  • 10,011
  • 16
  • 81
  • 129
  • 2
    an `EXC_BAD_ACCESS` is not an Objective-C exception but rather a problem with a dangling or invalid pointer. You try to use a pointer that points to no longer or invalid data. You should try by using Instruments tool to understand why object is corrupt. – Jack Oct 18 '13 at 16:14

1 Answers1

5

Don't catch exceptions unless the error is unrecoverable

This it not Java, read Try-catch exception handling practice for iPhone/Objective-C

And in any case don't catch NSException (PokemonExceptionHandling). If you really must catch an exception, you want to catch a specific one.


Back to your specific problem, EXC_BAD_ACCESS means that you are accessing the memory in a wrong way and the program just crashed. No exception is raised.

You have to look for dangling pointers or uninitialized variables that you are trying to access.

If you just want to perform different actions for different system versions, simply check the version and split the control flow, for instance:

if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_5_1) {
   // Do specific operations for iOS 5.1 or earlier
} else {
   // Do specific operations for iOS 6 or later
}

(source: How can we programmatically detect which iOS version is device running on?)

Community
  • 1
  • 1
Gabriele Petronella
  • 106,943
  • 21
  • 217
  • 235
  • The code works fine on iOS6 and 7 and I'm using ARC - would that not suggest that the problem isn't a dangling pointer? Thanks for your help. – Journeyman Oct 18 '13 at 16:37
  • ARC rules out many common issues with dangling **object** pointers, but not all of them. For instance `CGSize` is not an object so it's not managed by ARC. – Gabriele Petronella Oct 18 '13 at 16:48