Stu*_*Stu 139 objective-c selector
在MyClass.m中,我定义了
- (void) myTest: (NSString *) withAString{
NSLog(@"hi, %@", withAString);
}
Run Code Online (Sandbox Code Playgroud)
和MyClass.h中的适当声明.后来我打电话来
[self performSelector:@selector(mytest:withAString:) withObject: mystring];
Run Code Online (Sandbox Code Playgroud)
在MyClass.m但我得到一个类似于*终止应用程序的错误, 因为未捕获的异常'NSInvalidArgumentException',原因:'* - [MyClass myTest:withAtring:]:无法识别的选择器发送到实例0xe421f0'
我尝试了一个更简单的情况,一个选择器没有参数,打印一个字符串到控制台,并且工作得很好.代码有什么问题,我该如何解决?谢谢.
Sha*_*ney 311
在Objective-C中,选择器的签名包括:
选择者不知道:
这是一个类实现,其中performMethodsViaSelectors方法通过选择器执行其他类方法:
@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
Run Code Online (Sandbox Code Playgroud)
您要为其创建选择器的方法具有单个输入,因此您将为其创建一个选择器,如下所示:
SEL myTestSelector = @selector(myTest:);
Run Code Online (Sandbox Code Playgroud)
Lyn*_*son 135
您的方法签名是:
- (void) myTest:(NSString *)
Run Code Online (Sandbox Code Playgroud)
withAString恰好是参数(名称具有误导性,看起来它是选择器签名的一部分).
如果以这种方式调用该函数:
[self performSelector:@selector(myTest:) withObject:myString];
Run Code Online (Sandbox Code Playgroud)
它会工作.
但是,正如其他海报所建议的那样,您可能想要重命名该方法:
- (void)myTestWithAString:(NSString*)aString;
Run Code Online (Sandbox Code Playgroud)
并致电:
[self performSelector:@selector(myTestWithAString:) withObject:myString];
Run Code Online (Sandbox Code Playgroud)
Lir*_*rik 13
@Shane Arney
performSelector:withObject:withObject:
Run Code Online (Sandbox Code Playgroud)
您可能还想提一下,此方法仅用于传递最多2个参数,并且不能延迟.(如performSelector:withObject:afterDelay:)
.
有点奇怪,苹果只支持2个对象发送,并没有使它更通用.
您的代码有两个问题.一个被确认并回答,但另一个没有.第一个是你的选择器缺少其参数的名称.但是,即使您修复了该行,该行仍将引发异常,假设您修改的方法签名仍包含多个参数.假设您修改后的方法声明为:
-(void)myTestWithString:(NSString *)sourceString comparedTo:(NSString *)testString ;
Run Code Online (Sandbox Code Playgroud)
为具有多个参数的方法创建选择器是完全有效的(例如@selector(myTestWithString:comparisonTo :)).但是,performSelector方法只允许您将一个值传递给myTest,不幸的是,myTest有多个参数.它会报错并告诉您没有提供足够的值.
您可以随时重新定义您的方法以获取集合,因为它是唯一的参数:
-(void)myTestWithObjects:(NSDictionary *)testObjects ;
Run Code Online (Sandbox Code Playgroud)
但是,有一个更优雅的解决方案(不需要重构).答案是使用NSInvocation的,与它一起setArgument:atIndex:
和invoke
方法.
如果你想了解更多细节,我已经写了一篇文章,包括一个代码示例.重点是线程,但基础仍然适用.
祝好运!
归档时间: |
|
查看次数: |
209415 次 |
最近记录: |