Posts tagged Debugging

iPhone Memory Debugging with NSZombie and Instruments

NSZombie is easily one of the most valuable tools in any Cocoa developer’s toolbox. Check out Mark’s blog for a great introduction on using NSZombie from within Instruments:

iPhone Memory Debugging with NSZombie and Instruments | markjnet.

Thanks to Jeff LaMarche for directing me to Mark’s blog in the first place.

UIView Manipulation Made Easier with a Category

I was watching a presentation recently where the presenter showed the header for a category that he had added to UIView to make his life a little easier. The point of the talk did not center around the category so I never saw much more than the header, but that was all I needed to recreate it for my use. Here’s the header:

#import <uikit/UIKit.h>
 
@interface UIView (MFAdditions)
 
- (id) initWithParent:(UIView *)parent;
+ (id) viewWithParent:(UIView *)parent;
 
// Position of the top-left corner in superview's coordinates
@property CGPoint position;
@property CGFloat x;
@property CGFloat y;
 
// Setting size keeps the position (top-left corner) constant
@property CGSize size;
@property CGFloat width;
@property CGFloat height;
 
@end

As you can see there isn’t a whole lot to this category, but if you’re doing a lot of view manipulation the benefits of it will rapidly become clear. There was one sticky wicket that I hit when implementing this class and it centers around this method:

+ (id) viewWithParent:(UIView *)parent;

When I first implemented this method I wrote it like so:

+ (id) viewWithParent:(UIView *)parent {
	return [[[UIView alloc] initWithParent:parent] autorelease];
}

This was all well and good as long as the only class that I was creating was a UIView, but I ran into trouble when I started creating UIImageViews. Instantiating new UIImageViews worked fine, but as soon as I called a UIImageView-specific method the app would crash:

*** -[UIView setImage:]: unrecognized selector sent to instance 0xd1b350

I struggled with the answer to this one for a while and it wasn’t until I presented my problem to the local CocoaHeads group did I get it all figured out. Here’s the correct way to write this method:

+ (id) viewWithParent:(UIView *)parent {
	return [[[self alloc] initWithParent:parent] autorelease];
}

By calling self instead of strongly typing the returned object as a UIView the class would dynamically determine the correct type at runtime.

You can download this category here: UIViewAdditions

Quick and Easy Drawing Performance Debugging with NSShowAllDrawing

While watching one of the WWDC09 session videos I was informed of a great tip that I had been previously unknown to me: Pass -NSShowAllDrawing YES as an argument to your application in Xcode to see a visual representation of the drawing that your application performs as it runs.

To illustrate how NSShowAllDrawing works and the issues it can help you correct I’ve put together two videos.  The first shows my app, Bezipped, in its current 1.0 state and its current drawing behavior.

This second video shows how I improved the drawing in Bezipped simply by setting the top-level container to be backed by a Core Animation layer:

I highly recommend giving your app a spin with NSShowAllDrawing if you haven’t already, it was certainly a real eye-opener for me.  There are some additional resources for debugging your drawing performance on OS X (as pointed out to me by André Pang) provided by Apple here: Drawing Performance Guidelines: Measuring Drawing Performance

Lastly, both Alan Rogers and Steve Streza pointed me towards Quartz Debug.app (included with the developer tools) as another means to see similar redrawing behavior.  I found Quartz Debug’s options to be a bit heavy-handed as the drawing performance of the entire OS was shown instead of just my app, but your mileage may vary.