Reputation: 91
I would like to create an NSArray of Methods.
I have the following code :
- (void) showText { NSLog(@"text1"); }
- (void) showText2 { NSLog(@"text2"); }
- (void) showText3 { NSLog(@"text3"); }
I would like to do something like this :
arrayOfMethods = [NSArray arrayWithObjects:[self showText], [self showText2],
[self showText3], nil];
but it seems to not work because the return value is void and not an (id). But that's what i want !
The final goal is this :
[cell.button addTarget:self action:@selector([arrayOfMethods
objectAtIndex:indexPath.item]) forControlEvents:UIControlEventTouchUpInside];
Upvotes: 1
Views: 159
Reputation: 535202
This would be a lot easier in Swift, because in Swift when you call addTarget:action:forControlEvents:
what you pass for action:
is a string. Thus you could just keep an array of strings.
So, your array would look like:
let arr = ["showText", "showText2", "showText3"]
...and you'd be all set. You'd pass e.g. arr[1]
directly to action:
when you call addTarget:action:forControlEvents:
.
As it turns out, you didn't really need to "Make an Array of Methods", nor would it have done you any good to do so, because the action:
parameter is a selector, not a method. However, the more general question you seemed to be asking - how to store an actual array of methods - is also trivial in Swift, because in Swift, methods are objects and can be stored in an array:
typealias V = () -> ()
var arr = V[]()
func showtext1 () { println ("text1") }
func showtext2 () { println ("text2") }
func showtext3 () { println ("text3") }
func makeArray () { // here's how to make the array
arr = [self.showtext1, self.showtext2, self.showtext3]
}
func callArray () { // here's how to call all the methods in the array
for m in arr {m()}
}
Upvotes: 0
Reputation: 11693
You may want to use block and pass them to a method and execute it.
NSArray *callbacks = @[
^(){
// do some magics stuff
},
^(){
// do some magics stuff
},
];
execute([callbacks objectAtIndex:0])
-(void) execute:(void (^)())block{
block();
}
Upvotes: 3
Reputation: 124997
Methods are not objects, so aren't eligible to be stored in an NSArray. You could store strings to be used as selectors in an array, or you could store blocks that call the methods in question in an array, but not the methods themselves.
Array of strings for selectors:
NSArray *selectors = @[@"showText", @"showText2", @"showText3"];
You can then call one of these, say the middle one, like this:
SEL selector = NSSelectorFromString(selectors[1]);
[someObject performSelector:selector];
For the case you're considering, it's not clear that you even need methods at all; an array of blocks would do nicely.
Upvotes: 4
Reputation: 53111
You could try an array of NSInvocations
:
NSArray * invocations = @[ [NSInvocation invocationWithMethodSignature: [NSMethodSignature methodSignatureForSelector: @selector(showText)]],
[NSInvocation invocationWithMethodSignature: [NSMethodSignature methodSignatureForSelector: @selector(showText2)]],
[NSInvocation invocationWithMethodSignature: [NSMethodSignature methodSignatureForSelector: @selector(showText3)]]];
UIButton * button;
for (NSInvocation * invocation in invocations) {
[button addTarget: self action: invocation.selector forControlEvents: UIControlEventTouchUpInside];
}
Upvotes: 0
Reputation: 754
There are several ways to solve this, here's one that most closely matches your current implementation:
arrayOfMethods = @[ NSStringFromSelector(showText), NSStringFromSelector(showText2), NSStringFromSelector(showText3) ];
And then..
[cell.button addTarget:self action:NSSelectorFromString([arrayOfMethods
objectAtIndex:indexPath.item]) forControlEvents:UIControlEventTouchUpInside];
(..error handling omitted for clarity..)
Other options include use of Blocks or using NSInvocation objects.
Upvotes: 1
Reputation: 25459
You can create C array with selectors:
SEL selectors[] = {@selector(showText), @selector(showText2), @selector(showText3)};
And after that just call it like that:
[cell.button addTarget:self action:selectors[indexPath.item] forControlEvents:UIControlEventTouchUpInside];
Please note that it will show warnings because selector is be unknown in compile time.
Upvotes: 0
Reputation: 2252
You may also use NSOperationQueue
and NSInvocationOperation
to store selectors and manage them. Here is a good tutorial:
http://code.tutsplus.com/tutorials/working-with-the-nsoperationqueue-class--mobile-14993
Upvotes: 0
Reputation: 21726
Something like that:
arrayOfMethods = [NSArray arrayWithObjects:NSStringFromSelector(@selector(showText)), .., nil];
...
SEL action = NSSelectorFromString([arrayOfMethods
objectAtIndex:indexPath.item])
[cell.button addTarget:self action:action forControlEvents:UIControlEventTouchUpInside];
Upvotes: 1