我想创建一个NSArray方法。
我有以下代码:
- (void) showText { NSLog(@"text1"); }
- (void) showText2 { NSLog(@"text2"); }
- (void) showText3 { NSLog(@"text3"); }
我想做这样的事情:
arrayOfMethods = [NSArray arrayWithObjects:[self showText], [self showText2],
[self showText3], nil];
但似乎不起作用,因为返回值为void而不是(id)。但这就是我想要的!
最终目标是:
[cell.button addTarget:self action:@selector([arrayOfMethods
objectAtIndex:indexPath.item]) forControlEvents:UIControlEventTouchUpInside];
答案 0 :(得分:4)
方法不是对象,因此不能存储在NSArray中。您可以存储要在数组中用作选择器的字符串,或者您可以存储在数组中调用相关方法的块,但不能存储方法本身。
选择器的字符串数组:
NSArray *selectors = @[@"showText", @"showText2", @"showText3"];
然后你可以打电话给其中一个,比如中间一个,就像这样:
SEL selector = NSSelectorFromString(selectors[1]);
[someObject performSelector:selector];
对于您正在考虑的情况,您根本不需要方法就不清楚了;一系列的块可以很好地完成。
答案 1 :(得分:3)
您可能希望使用块并将它们传递给方法并执行它。
NSArray *callbacks = @[
^(){
// do some magics stuff
},
^(){
// do some magics stuff
},
];
execute([callbacks objectAtIndex:0])
-(void) execute:(void (^)())block{
block();
}
答案 2 :(得分:1)
类似的东西:
arrayOfMethods = [NSArray arrayWithObjects:NSStringFromSelector(@selector(showText)), .., nil];
...
SEL action = NSSelectorFromString([arrayOfMethods
objectAtIndex:indexPath.item])
[cell.button addTarget:self action:action forControlEvents:UIControlEventTouchUpInside];
答案 3 :(得分:1)
有几种方法可以解决这个问题,这里有一个最接近你当前实现的方法:
arrayOfMethods = @[ NSStringFromSelector(showText), NSStringFromSelector(showText2), NSStringFromSelector(showText3) ];
然后..
[cell.button addTarget:self action:NSSelectorFromString([arrayOfMethods
objectAtIndex:indexPath.item]) forControlEvents:UIControlEventTouchUpInside];
(为清楚起见,省略了错误处理..)
其他选项包括使用Blocks或使用NSInvocation对象。
答案 4 :(得分:0)
您还可以使用NSOperationQueue
和NSInvocationOperation
来存储选择器并对其进行管理。这是一个很好的教程:
http://code.tutsplus.com/tutorials/working-with-the-nsoperationqueue-class--mobile-14993
答案 5 :(得分:0)
您可以使用选择器创建C数组:
SEL selectors[] = {@selector(showText), @selector(showText2), @selector(showText3)};
之后就这样称呼它:
[cell.button addTarget:self action:selectors[indexPath.item] forControlEvents:UIControlEventTouchUpInside];
请注意,它会显示警告,因为编译器中的选择器是未知的。
答案 6 :(得分:0)
您可以尝试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];
}
答案 7 :(得分:0)
这在Swift中会容易得多,因为在Swift中调用addTarget:action:forControlEvents:
时,action:
传递的是一个字符串。因此,您可以保留一个字符串数组。
所以,你的数组看起来像:
let arr = ["showText", "showText2", "showText3"]
......你会全力以赴。你会通过,例如当您拨打arr[1]
时,action:
会直接addTarget:action:forControlEvents:
。
事实证明,你真的不需要“制作一个方法数组”,也没有任何好处,因为action:
参数是一个选择器< / em>,不是方法。但是,你似乎要问的更普遍的问题 - 如何存储实际的方法数组 - 在Swift中也是微不足道的,因为在Swift,方法是对象,可以存储在数组中:
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()}
}