I recently discovered a pretty big performance issue in my app that was due to an image not being found in [UIImage imagenamed:].
I was wondering if there is a “drop-in” solution to have this kind of ‘errors’ logged in some way? I started writing an extension to the UIImage class, something like this:
@implementation UIImage (Debug)
#ifdef DEBUG
+ (UIImage*) imageNamed:(NSString*) name{
UIImage* img = [UIImage imageNamed:name];
if(!img){
NSLog(@"Error: referencing non-exiting image: %@", name);
}
return img;
}
#endif
@end
But this causes an endless loop since [UIImage imageNamed:name] of course causes the extension method to be called again…
Any suggestions?
thanks
Thomas
You should never use categories to override an existing method. This will lead to unexpected results (the implementation used will depend on the order the runtime loads the binary images/modules).
Instead, you may use the possibilities of the objc runtime to exchange implementations of one selector with another (sometimes called method swizzling). But I would discourage you to do this if you don’t really know the implications. (call the swapped method if you want to call the original to avoid call loops, manage the use case when the method is implemented in the parent class but not the child, and much more subtleties)
But if you only want to debug and be alerted when an UIImage is not found use symbol breakpoints ! (Breakpoints are not limited to be placed on a given line of code!)
Breakpoints are more powerful than you can imagine (I encourage you to watch the WWDC’11 video session about “mastering debugging in Xcode”), especially you can place a breakpoint not on a specific line in your code, but on a specific method call (in your case the method
-imageNamed:), and add a condition to the breakpoint so it will only be hit in certain condition (returned image nil?). You can even ask the breakpoint to log some info (or play a sound, or whatever) and/or continue execution instead of stopping your code execution.