Reputation: 3315
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;
}
Upvotes: 85
Views: 20232
Reputation: 5192
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.
Upvotes: 1
Reputation: 1448
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.
Upvotes: 1
Reputation: 4603
Could you store strings and use NSSelectorFromString?
From the docs
NSSelectorFromString
Returns the selector with a given name.
SEL NSSelectorFromString (
NSString *aSelectorName
);
Upvotes: 80
Reputation: 6958
You can also create an array of NSInvocation
s. 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
Upvotes: 13
Reputation: 523464
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]];
// ....
}
Upvotes: 37
Reputation: 8264
This creates an object out of selector:
[NSValue valueWithPointer:@selector(x)]
Upvotes: 44