Objective c 选择器未由methodSignatureForSelector发送到forwardInvocation
为了便于学习,我正在尝试更改对对象调用的方法。 这是我的密码Objective c 选择器未由methodSignatureForSelector发送到forwardInvocation,objective-c,Objective C,为了便于学习,我正在尝试更改对对象调用的方法。 这是我的密码 #import <Foundation/Foundation.h> @interface A : NSObject -(void) say: (NSString*) s; -(NSMethodSignature*) methodSignatureForSelector: (SEL) aSelector; -(void) forwardInvocation: (NSInvocation*) invocation; @end
#import <Foundation/Foundation.h>
@interface A : NSObject
-(void) say: (NSString*) s;
-(NSMethodSignature*) methodSignatureForSelector: (SEL) aSelector;
-(void) forwardInvocation: (NSInvocation*) invocation;
@end
@implementation A
-(void) say: (NSString*) s {
printf( "say \"%s\"", [s UTF8String] );
}
-(NSMethodSignature*) methodSignatureForSelector: (SEL) aSelector {
return [A instanceMethodSignatureForSelector: @selector(say:)];
}
-(void) forwardInvocation: (NSInvocation*) invocation {
// [invocation setSelector:@selector(say:)];
[invocation invokeWithTarget:self];
}
@end
int main(int args, char* argv[]){
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
A* myObject = [[[A alloc] init] autorelease];
[myObject tryToSay:@"Hello strange method!"];
[pool release];
return 0;
}
#导入
@接口A:NSObject
-(void)说:(NSString*)s;
-(NSMethodSignature*)方法签名选择器:(SEL)选择器;
-(void)转发调用:(NSInvocation*)调用;
@结束
@实施A
-(void)说:(NSString*)s{
printf(“说\%s\”,[s UTF8String]);
}
-(NSMethodSignature*)方法签名选择器:(SEL)选择器{
返回[A instanceMethodSignatureForSelector:@selector(say:)];
}
-(void)转发调用:(NSInvocation*)调用{
//[调用集合选择器:@selector(say:)];
[调用invokeWithTarget:self];
}
@结束
int main(int args,char*argv[]){
NSAutoreleasePool*池=[[NSAutoreleasePool alloc]init];
A*myObject=[[A alloc]init]autorelease];
[我的对象尝试说:@“你好,奇怪的方法!”;
[池释放];
返回0;
}
我想使用-say:无论尝试在类A的对象上使用哪个方法
结果是一个Segfault。
似乎发送到forwardInvocation的调用对象仍然有@selector(tryToSay:)作为其选择器。它不应该得到在methodSignatureForSelector中设置的相同选择器吗?不,它不是
NSMethodSignature
不会对选择器进行编码。它对方法的签名进行编码。这意味着参数的类型和数量。它也不能正常工作。如果有人试图调用像-setInteger:
这样的方法,该方法接受一个整数,它将被传递给您的方法-say:
,该方法需要一个NSString*
。但是它不会得到一个NSString*
,它会得到一个NSUInteger
,任何试图取消引用的操作都会崩溃(除非它是0)。那么我想我不明白为什么重写-methodSignatureForSelector:
如此重要。无论如何谢谢你!如果您不提供方法签名,并且运行时无法找到具有该选择器本身的方法,则它无法首先构造NSInvocation
。尽管有方法签名,我的示例还是导致崩溃的原因是NSUInteger
和NSString*
都以相同的方式传递到函数中(例如寄存器/堆栈)。问题是,如果将3
传入,则生成的-例如:
将尝试将3
视为对象指针,当取消引用时,它将崩溃。