制作一组方法
我想创build一个NSArray的方法。
我有以下代码:
- (void) showText { NSLog(@"text1"); } - (void) showText2 { NSLog(@"text2"); } - (void) showText3 { NSLog(@"text3"); }
我想要做这样的事情:
arrayOfMethods = [NSArray arrayWithObjects:[self showText], [self showText2], [self showText3], nil];
但它似乎不工作,因为返回值是无效的,而不是(id)。 但那就是我想要的!
最终的目标是:
[cell.button addTarget:self action:@selector([arrayOfMethods objectAtIndex:indexPath.item]) forControlEvents:UIControlEventTouchUpInside];
类似的东西:
arrayOfMethods = [NSArray arrayWithObjects:NSStringFromSelector(@selector(showText)), .., nil]; ... SEL action = NSSelectorFromString([arrayOfMethods objectAtIndex:indexPath.item]) [cell.button addTarget:self action:action forControlEvents:UIControlEventTouchUpInside];
方法不是对象,所以不适合存储在NSArray中。 您可以将string存储为数组中的select器,也可以将调用方法的块存储在数组中,而不是方法本身。
select器的string数组:
NSArray *selectors = @[@"showText", @"showText2", @"showText3"];
然后你可以打电话给其中的一个,比如中间的那个,就像这样:
SEL selector = NSSelectorFromString(selectors[1]); [someObject performSelector:selector];
对于你正在考虑的情况,目前还不清楚你甚至需要什么方法; 一堆块将很好地做。
您可能想要使用块并将它们传递给方法并执行它。
NSArray *callbacks = @[ ^(){ // do some magics stuff }, ^(){ // do some magics stuff }, ]; execute([callbacks objectAtIndex:0]) -(void) execute:(void (^)())block{ block(); }
有几种方法可以解决这个问题,这里最接近你当前的实现:
arrayOfMethods = @[ NSStringFromSelector(showText), NSStringFromSelector(showText2), NSStringFromSelector(showText3) ];
接着..
[cell.button addTarget:self action:NSSelectorFromString([arrayOfMethods objectAtIndex:indexPath.item]) forControlEvents:UIControlEventTouchUpInside];
(..error handling省略了清晰..)
其他选项包括使用块或使用NSInvocation对象。
您也可以使用NSOperationQueue
和NSInvocationOperation
存储select器并对其进行pipe理。 这里是一个很好的教程: http : //code.tutsplus.com/tutorials/working-with-the-nsoperationqueue-class–mobile-14993
你可以用select器创buildC数组:
SEL selectors[] = {@selector(showText), @selector(showText2), @selector(showText3)};
之后就这样叫:
[cell.button addTarget:self action:selectors[indexPath.item] forControlEvents:UIControlEventTouchUpInside];
请注意,它会显示警告,因为在编译时select器是未知的。
你可以尝试一个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]; }
这在Swift中会容易得多,因为在Swift中当你调用addTarget:action:forControlEvents:
你传递给action:
是一个string 。 因此,你可以保留一个string数组。
所以,你的数组看起来像:
let arr = ["showText", "showText2", "showText3"]
…你会一切设置。 你可以直接将arr[1]
传递给action:
当你调用addTarget:action:forControlEvents:
事实certificate,你并不需要“创build一个数组方法”,也不会做任何好事,因为action:
参数是一个select器 ,而不是一个方法。 然而,你似乎要问的更一般的问题 – 如何存储一个实际的方法数组 – 在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()} }