views:

554

answers:

2

It sure seems like the Xcode debugger has been playing a dirty trick on me for the last couple hours.

I was working with this code which has--in hindsight--a pretty obvious bug, but it wasn't obvious at the time:

- (UIImage*)loadBundleImage:(NSString*)imageName {   
    NSBundle* bundle = [NSBundle mainBundle];
    NSString* path = [bundle bundlePath];
    path = [path stringByAppendingFormat:@"%@/%@", path, imageName];
    return [UIImage imageWithContentsOfFile:path];
}

I was using the debugger to step through the code, and it kept saying that bundle was nil after the [NSBundle mainBundle] call. This led me to search high and low for why that could possibly be and to try to fix that problem.

Ultimately, I found the actual bug (which was that I was appending the path twice), so I decided to do some experimenting... obviously, bundle wasn't nil, so why was the debugger saying it was? When stepping through this code, the debugger correctly shows the value of bundle after the mainBundle call:

- (UIImage*)loadBundleImage:(NSString*)imageName {   
    NSBundle* bundle = [NSBundle mainBundle];
    if (bundle == nil) {
     NSLog(@"Nil bundle");
    }
    NSString* path = [bundle bundlePath];
    path = [path stringByAppendingFormat:@"/%@",imageName];
    return [UIImage imageWithContentsOfFile:path];
}

So, what gives here? Is it a bug with the debugger? My only wild guess is that the compiler is optimizing the consecutive calls to mainBundle and bundlePath into some sort of atomic-ish operation, so the debugger doesn't get to "see" what happened... but that when I broke those two calls up with the if-block... that forced the compiler to deal with them separately?!

Can anyone shed some light on this? Am I as crazy as I feel? Please tell me I'm wrong and that I can go back to trusting the debugger.

Thanks, sorry for the mini-rant, there.

A: 

I see you have already resolved the issue, but in the newest XCode build the debugger console should say "variable X has been optimized away" when you try to print it in a release build.

Kendall Helmstetter Gelner
I'm marking this as the accepted answer, just so I don't get dinged for not accepting answers. (jib's comment above is the actual answer... but comments can't be accepted as answers.)
Rob
A: 

You should be using stringByAppendingPathComponent: to build your path, not tagging on slashed characters. I have a standard category on UIImage that gets images from the Resources folder:

+(UIImage*)imageFromResourceFileNamed:(NSString*)name;
{
if(!name) return nil;
NSString *path = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:name];
return [[[UIImage alloc] initWithContentsOfFile:path] autorelease];

}

Use it like this:

UIImage *prettyImage = [UIImage imageFromResourceFileNamed:@"flower.png"];
Steve Weller