Cool Stuff in Cocoa and Objective-C
In my travels through Objective C and Cocoa Programming, I've come
across some random bits of coolness.
Last updated April 2, 2002.
- PoseAsClass is really cool. You can have your own class become
any other class, allowing you to do some work, and then forward up the
inheritance chain. Big deal? When you pose as, your class gets used whenever
the other class would be used. For example - to peek at a textview when
they're drawn anywhere in your program (even from the font and color panels)
@interface TextViewPoser : NSTextView
@end // TextViewPoser
@implementation TextViewPoser
- (void) drawRect: (NSRect) bounds
{
NSLog (@"drawRect");
[super drawRect: bounds];
} // drawRect
@end // TextViewPoser
Then in your main.m (or somewhere convenient)[[TextViewPoser class] poseAsClass: [NSTextView class]];
- Using categories, you can put methods on other classes, including
the pre-canned toolkit classes. For example, this makes NSViews draw
their backgrounds in yellow by default, which will cause windows to take on
a yellow cast:
@implementation NSView (BWYellowView)
- (void) drawRect: (NSRect) rect
{
NSColor *transparentYellow;
rect = [self bounds];
transparentYellow = [NSColor colorWithCalibratedRed: 1.0
green: 1.0
blue: 0.0
alpha: 0.333];
[transparentYellow set];
[NSBezierPath fillRect: rect];
} // rect
- NSObject's "valueForKey" and "takeValue" methods. These let you
set and get values in an arbitrary object by name
NSString *identifier = [aTableColumn identifier];
Person *person = [employees objectAtIndex: rowIndex];
return ([person valueForKey: identifier]);
Why is this cool? By changing the value of the identifier, you can
change the field of the Person object you'll be accessing. e.g. you
can change which part of the object you're manipulating in Interface
Builder and not have to recompile code. Also, it lets you avoid having
to write (and maintain) the nasty idiom of
if (identifier is "oop") {
return (person.oop);
} else if (identifier is "ack") {
return (person.ack);
} ...
- Delegation in objective C uses the 'respondsToSelector:' method of
NSObject. If you want to see all the different selectors your object is
being asked about, add this to your class:
- (BOOL)respondsToSelector: (SEL)aSelector
{
NSString *methodName = NSStringFromSelector (aSelector);
NSLog (@"respondsToSelector: %@", methodName);
return ([super respondsToSelector: aSelector]);
} // respondsToSelector