Re: Abstracting a group of commonly named Selectors

Jeff Laing

In the designated initialise of your Parser class, you can use class_addMethod to add whatever you like to your instance's class.

The method implementation gets called with the selector as its second argument and you can cut the string up at runtime to then call your Parse. Here's a snippet from an app I did in the past that wanted to dynamically adjust to any entries that were added to a popup menu in Interface Builder. It iterates over the popup, and for every entry present, looks for then adds a dynamic method called _popup.

        IMP popup_imp = class_getMethodImplementation([self class], @selector(_popup00:));
        for (NSArray *item in popup) {
                // make sure that we implement the required method
                SEL sel = NSSelectorFromString([NSString stringWithFormat:@"_popup%02ld:",(long)[menuItems count]]);
                if (![self respondsToSelector:sel]) {
                        class_addMethod([self class], sel, popup_imp, "v@:@");  // -(void)method:(id)argument;

The implementation of the method gets the name of the selector using set_getName, then punts across to the actual code.

- (void)_popup00:(id)sender {
//          01234567
        const char *name = sel_getName(_cmd);
        const int idx = atoi(name+6);
        id resp = [self.popupResponders objectAtIndex:idx];
        [resp callWithArrayOfArgs:self.popupArguments];

Extracting your specific token from the message is just name+. This example is using (void) but it should work just fine - you aren't using the "no such method" path, you are just binding the method really late in the compile/link/run process...

Join { to automatically receive all group messages.