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器的签名包括:
- 方法的名称(在这种情况下,它将是'myTest')(必需)
- 如果方法有一个input,则在方法名称后面跟一个':'(冒号)。
- 每一个额外的input名称和“:”。
select器不知道:
- inputtypes
- 该方法的返回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你自己的逻辑来实现这一点。