2009
5/29

The Secret Life of _cmd







6Tringle's featured product: PhotoClay Logo Photo mushing fun with your finger

Buy app through iTunes








We enthusiastically recommend:

An Objective-C class in Cocoa has one hidden object that every knows about. The self object is used extensive within a class to reference the object currently invoking a method.

There is another hidden variable that very few seem to know about: _cmd.

_cmd is the method that is currently being invoked. So if self is the subject, _cmd is the verb.

The most obvious application of _cmd is logging. Here is one of my most used macros:

#define METHOD_LOG (NSLog(@"%@ %s\n%@", \
                    NSStringFromSelector(_cmd), \
                    __FILE__, self))

You would typically use it in a method like follows:

- (void)viewDidLoad
{
    METHOD_LOG;

    //do stuff...
}

This logs a message to the console telling, what method, from what file, invoked with what object.

Tremendously useful. Here's a second version that adds thread information:

#define METHOD_LOG_THREAD (NSLog(@"%@ %@ %s\n%@", \
                        NSStringFromSelector(_cmd), \
                        [NSThread currentThread], \
                        __FILE__, self))

_cmd is not only for logging. We can play neat tricks with it as well.

This method returns an object in a dictionary where the key is the method name,

- (id)color;
{
    //SomeDictionary defined elsewhere in class
    return [SomeDictionary 
            objectForKey:NSStringFromSelector(_cmd)];
}

You could combine this with a property to get easy access inside a dictionary.

@property (readonly) id color;

If you wanted a read-write property, you could implement it this way:

- (id)color;
{
    //SomeDictionary defined elsewhere in class
    return [SomeDictionary objectForKey:
                [NSStringFromSelector(_cmd) capitalize]];
}
- (void)setColor:(id)someObject;
{
    //3 means we start from the C in Color
    NSString *partial_string;
    partial_string = [NSStringFromSelector(_cmd) 
                        substringFromIndex:3];

    //SomeDictionary defined elsewhere in class
    [SomeDictionary setObject:someObject 
                       forKey:partial_string]; 
}

Now, we have a color property, without ever creating a color instance variable in the class. This has some advantages in that you don't have worry as much about memory management. The object is retained when it's added to SomeDictionary and released when SomeDictionary is released or when the object is replaced.

The Objective-C runtime is full of neat little tricks and _cmd is just one of them.

More advanced techniques can be used to implement some advanced functionality such as higher-order-messaging and even mimic methods as nearly first class objects.

Functional programming aficionados can check out http://www.cocoadev.com/index.pl?HigherOrderMessaging for some discussion on this.

Products of unassailable virtue and rectitude

about products blog contact misc xml