2005/03/09
Obj-C runtime fun
Some time ago, I discovered this neat little tool, LJV (for "Lightweight Java Visualizer"). Basically, a small Java program that takes a data structure as input, and generate a GraphViz file as output.
So of course, I had this irrepressible urge to hack something similar for Objective-C.
Let's take the following Obj-C code:
@interface Bi : NSObject {
NSString* xxa;
}
@end
@interface Bo : Bi {
NSString* d;
id e;
}
@end
@implementation Bo
-(id)init
{
[super init];
e = [[NSScanner scannerWithString:@"asdfasdf asdf"] retain];
return self;
}
@end
@interface Ga : NSObject {
NSString* grunt;
NSMutableArray* a;
Bo* x;
}
@end
@implementation Ga
-(id)init
{
[super init];
grunt = @"pok";
a = [[NSArray alloc] initWithObjects:@"ag",
[NSString stringWithString:@"b"],
nil];
x = [[Bo alloc] init];
return self;
}
@end
(yes, I know, I did not code release methods, I'm leaking). Just use some magical NSObject category:
Ga* g = [[Ga alloc] init];
[g dumpObjectGraph];
[g dumpObjectGraph];
And shazam !

- Objective-C is not Java, and introspection API is simpler, but /usr/include/objc/objc-class.h and friends are enough for this.
- This works reasonably well, even for some large programs, with one caveat: if you have garbage in one of your ivar, you're dead. It's not a problem most of the time but when I tried this on some AppKit code, it crashed. This could be fixed by maintaining a list of classes that should not be introspected.
- I need to cleanup the source code and put this on the web somewhere.
update: I wrote a new post with additional explanations and the source code on