Question

I'm trying to implement a dispatch table, so that I can call a selector with the following example code:

NSInteger i = 2;
[myObject performSelector:selectors[i]];

I'm trying to store user preferences which affect which method of an API gets called. Right now, I use the string name of the selector and use NSSelectorFromString, but that's a bit messy. If I use a dispatch table, then I can store an enum instead.

How can I make an array of selectors, or a dispatch table in Objective-C?

Edit:

The compiler complains when I try to set an array of selectors as a property. @property SEL[] won't compile.

Edit2:

I'm using my KosherCocoa API library and I want to call a single method at once, based on a saved user setting. I'm saving to and reading from a Plist file.

Was it helpful?

Solution

You can use the SEL type to hold selectors. Simply:

SEL dispatchTable[3] = { @selector(doThis:), 
                         @selector(doThat:), 
                         @selector(doTheOther:) 
                       };

To your edit, use an NSArray/NSDictionary/etc of selectors as your property instead. You are not allowed to use C arrays as properties in Objective C; they are not one of the supported types (which are ObjC objects, CF types and basic C 'Plain Old Data' types.)

OK, on our comments below, you need to wrap the selector in an NSValue to allow you to use it in an objc container (because SEL is a C pointer type):

NSMutableArray * dispatchTable2 = [[NSMutableArray alloc] initWithCapacity:3];
SEL selIn = @selector(doThis:);

// Wrap the selector in an NSValue instance
[dispatchTable2 addObject:[NSValue valueWithPointer:selIn]];

// On extracting:
NSValue * valOut = [dispatchTable2 objectAtIndex:0];
SEL selOut = [[dispatchTable2 objectAtIndex:0] pointerValue];
[anObject performSelector:selOut];

So now your table is an objc container stored as a property or ivar, and you use NSValue to wrap SEL pointers with valueWithPointer: and get the SEL out with pointerValue.

OTHER TIPS

I would recommend using NSInvocation instead of selectors. They are far more flexible, as you can send the same invocation to many objects and you can change its properties as you go.

One way to do this is using an array of NSStrings, then converting those to SELs at runtime, if that increases readability for you..

NSString *selectors[] = { ... } 

[myObject performSelector:NSSelectorFromString(selectors[i])];

To use this as a property, use

@property(nonatomic, assign) NSString **selectors;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top