Blog Archives

Objective-C Quickie – Printing the name of a method

Getting the name of a method as a string is quite easy in objective-c.  This quickie is useful for logging, or in my case raising an exception if the method is not overridden by a subclass:

NSString *methodName = NSStringFromSelector(_cmd);

NSStringFromSelector is pretty straightforward, and _cmd is one of the two hidden parameters to every objective-c selector (along with self).

Advertisements

Jeff LaMarche on the runtime and properties

Some time ago I posted about printing all the properties of an object using the runtime.  I was poking around the NSConference site today and found a talk by Jeff LaMarche on the same topic talking about ways to use the runtime in your application design patterns:

Cocoa Design Patterns that Leverage the Objective-C Runtime (NSConference 2010) from iDeveloper TV on Vimeo.

Objective-C Quickie : Printing all declared properties of an object

Here’s some quick code that will print the values of all declared properties of an object using some of the introspection features of the runtime. This assumes that you’re using the default getter and setter names:


- (NSString *)description
{
    NSMutableString *string = [NSMutableString stringWithString:@""];
    unsigned int propertyCount;
    objc_property_t *properties = class_copyPropertyList([self class], &propertyCount);
    
    for (unsigned int i = 0; i < propertyCount; i++)
    {
        NSString *selector = [NSString stringWithCString:property_getName(properties[i]) encoding:NSUTF8StringEncoding] ;
        
        SEL sel = sel_registerName([selector UTF8String]);
        
        const char *attr = property_getAttributes(properties[i]);
        switch (attr[1]) {
            case '@':
                [string appendString:[NSString stringWithFormat:@"%s : %@\n", property_getName(properties[i]), objc_msgSend(self, sel)]];
                break;
            case 'i':
                [string appendString:[NSString stringWithFormat:@"%s : %i\n", property_getName(properties[i]), objc_msgSend(self, sel)]];
                break;
            case 'f':
                [string appendString:[NSString stringWithFormat:@"%s : %f\n", property_getName(properties[i]), objc_msgSend(self, sel)]];
                break;
            default:
                break;
        }
    }
    
    free(properties);
    
    return string;

}

As you can see, I’m using this so that NSLog will give me something meaningful by overriding the description method of NSObject.
Edit: If you call this from a subclass, this method will only print the properties of the declared type!