How to create an "array of selectors"

IosObjective CNsarraySelector

Ios Problem Overview


I'm using the iPhone SDK (3.0) and I'm trying to create an array of selectors to invoke a variety of methods within one class.

Obviously, I'm doing something wrong (I think @selector isn't considered a class and so stuffing them into an NSArray isn't working).

I tried this, but it's obviously wrong.

Is there a simple way to have an array of selectors like this? Or is there a better way to iterate through a collection of methods?

selectors = [NSArray arrayWithObjects:
                          @selector(method1),
                          @selector(method2),
                          @selector(method3),
                          @selector(method4),
                          @selector(method5),
                          @selector(method6),
                          @selector(method7), nil];

for (int i = 0; i < [selectors count]; i++) {
    if ([self performSelector:[selectors objectAtIndex:i]]) // do stuff;
}

Ios Solutions


Solution 1 - Ios

Could you store strings and use NSSelectorFromString?

From the docs

NSSelectorFromString

Returns the selector with a given name.

SEL NSSelectorFromString (
   NSString *aSelectorName
);

Solution 2 - Ios

This creates an object out of selector:

[NSValue valueWithPointer:@selector(x)]

Solution 3 - Ios

Why not just use a simple C array?

static const SEL selectors[] = {@selector(method1),
                                ....
                                @selector(method7)};

...

for (int i = 0; i < sizeof(selectors)/sizeof(selectors[0]); i++) {
  [self performSelector:selectors[i]];
  // ....
}

Solution 4 - Ios

You can also create an array of NSInvocations. This is handy if you need an argument to go with your selector.

NSMethodSignature *sig = [[yourTarget class] instanceMethodSignatureForSelector:yourSEL];
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:sig];
[inv setTarget:yourTarget];
[inv setSelector:yourSEL];
[inv setArgument:&yourObject atIndex:2]; // Address of your object

Solution 5 - Ios

If the list is static, I'd go with KennyTM's solution, but if you need a dynamic array or set, another option, besides storing the selector string, is to create an object with an SEL property or ivar, and store that.

@interface SelectorObject : NSObject
@property (assign, readonly, nonatomic) SEL selector;
- (id)initWithSelector:(SEL)selector;
@end

@implementation SelectorObject
- (id)initWithSelector:(SEL)selector {
  self = [super init];
  if (self) {
    _selector = selector;
  }
  return self;
}
@end

You could then add a perform method to the class as well, and implement the method call there.

Solution 6 - Ios

I'd like to supplement two methods of storing selectors in an array,

First, NSPointerArray can store opaque pointer, such as SEL, as Apple doc said,

NSPointerArray *selectors = [[NSPointerArray alloc] initWithOptions: NSPointerFunctionsOpaqueMemory];
[selectors addPointer:@selector(onSendButton:)];
[button addTarget: self action:[selectors pointerAt:0] forControlEvents:UIControlEventTouchUpInside];

Second, C-style array is much simpler,

SEL selectors[] = { @selector(onSendButton:) };
[button addTarget: self action:selectors[0] forControlEvents:UIControlEventTouchUpInside];

Choose any as you wish.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser141146View Question on Stackoverflow
Solution 1 - IosJesse AndersonView Answer on Stackoverflow
Solution 2 - IosDenNukemView Answer on Stackoverflow
Solution 3 - IoskennytmView Answer on Stackoverflow
Solution 4 - IosMorrowlessView Answer on Stackoverflow
Solution 5 - Iosbig_mView Answer on Stackoverflow
Solution 6 - IosDawnSongView Answer on Stackoverflow