Objective-C:调用具有多个参数的select器

在MyClass.m中,我已经定义了

- (void) myTest: (NSString *) withAString{ NSLog(@"hi, %@", withAString); } 

和MyClass.h中的相应声明。 后来我想打电话

 [self performSelector:@selector(mytest:withAString:) withObject: mystring]; 

在MyClass.m但我得到一个错误类似于*终止应用程序由于未捕获exception'NSInvalidArgumentException',原因:'* – [myClass myTest:withAtring:]:无法识别的select发送到实例0xe421f0'

我尝试了一个更简单的情况下,select器没有任何参数,打印到控制台的string,工作得很好。 代码有什么问题,我该如何解决? 谢谢。

您的方法签名是:

 - (void) myTest:(NSString *) 

withAString碰巧是参数(名称是误导性的,它看起来像是select器签名的一部分)。

如果你以这种方式调用函数:

 [self performSelector:@selector(myTest:) withObject:myString]; 

它会工作。

但是,正如其他海报所build议的,您可能需要重命名该方法:

 - (void)myTestWithAString:(NSString*)aString; 

并致电:

 [self performSelector:@selector(myTestWithAString:) withObject:myString]; 

在Objective-C中,select器的签名包括:

  1. 方法的名称(在这种情况下,它将是'myTest')(必需)
  2. 如果方法有一个input,则在方法名称后面跟一个':'(冒号)。
  3. 每一个额外的input名称和“:”。

select器不知道:

  1. inputtypes
  2. 该方法的返回types。

下面是一个类实现,其中performMethodsViaSelectors方法通过select器执行其他类方法:

 @implementation ClassForSelectors - (void) fooNoInputs { NSLog(@"Does nothing"); } - (void) fooOneIput:(NSString*) first { NSLog(@"Logs %@", first); } - (void) fooFirstInput:(NSString*) first secondInput:(NSString*) second { NSLog(@"Logs %@ then %@", first, second); } - (void) performMethodsViaSelectors { [self performSelector:@selector(fooNoInputs)]; [self performSelector:@selector(fooOneInput:) withObject:@"first"]; [self performSelector:@selector(fooFirstInput:secondInput:) withObject:@"first" withObject:@"second"]; } @end 

你想创build一个select器的方法只有一个input,所以你可以像这样创build一个select器:

 SEL myTestSelector = @selector(myTest:); 

@Shane Arney

 performSelector:withObject:withObject: 

你也许还想提一下,这个方法只能传递最多2个参数,不能被延迟。 (比如performSelector:withObject:afterDelay:)

有点奇怪,苹果只支持2个对象发送,并没有使其更通用。

你的代码有两个问题。 一个被确认和回答,但另一个不是。 首先是你的select器缺less参数的名字。 然而,即使你修正了这个问题,假设你修改的方法签名仍然包含多个参数,那么这行仍然会引发一个exception。 假设您的修改方法被声明为:

 -(void)myTestWithString:(NSString *)sourceString comparedTo:(NSString *)testString ; 

为具有多个参数的方法创buildselect器是完全有效的(例如@selector(myTestWithString:comparisonTo :))。 然而,performSelector方法只允许你传递一个值给myTest,不幸的是它有多个参数。 它会错误地告诉你,你没有提供足够的价值。

你总是可以重新定义你的方法采取一个集合,因为它只是参数:

 -(void)myTestWithObjects:(NSDictionary *)testObjects ; 

但是,有一个更优雅的解决scheme(不需要重构)。 答案是使用NSInvocation,以及它的setArgument:atIndex:invoke方法。

我写了一篇文章,包括一个代码示例 ,如果你想要更多的细节。 重点在于线程,但是基础仍然适用。

祝你好运!

你的方法签名没有意义,你确定它不是一个错字吗? 我不清楚它是如何编译的,虽然也许你得到了一个你无视的警告。

你期望这个方法有多less个参数?

认为这个类应该被定义为:

 - (void) myTestWithSomeString:(NSString *) astring{ NSLog(@"hi, %s", astring); } 

你只有一个参数,所以你应该只有一个:

你也许会考虑在你的NSLog中使用%@ – 这只是一个很好的习惯 – 然后写出任何对象 – 而不仅仅是string。

iOS用户也期待自动资产化:在标准文本字段中,区分大小写的语句的首字母会自动大写。

您可以决定是否实施这些function; 没有任何上述function的专用API,所以提供它们是一个竞争优势。

苹果公司的文件说这个function没有可用的API,而在自定义键盘上有一些其他预期的function。 所以你需要find你自己的逻辑来实现这一点。