селектор не отправлен методом methodSignatureForSelector для forwardInvocation - PullRequest
2 голосов
/ 22 января 2011

Я пытаюсь изменить, какой метод вызывается для объекта ради обучения. Вот мой код.

#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;
}

Я хочу использовать -say: независимо от того, какой метод используется для объектов класса A.

Результатом является Segfault. Кажется, объект вызова, отправленный forwardInvocation, все еще имеет @selector (tryToSay :) в качестве селектора. Разве не предполагается получить тот же селектор, который был установлен в methodSignatureForSelector?

1 Ответ

3 голосов
/ 22 января 2011

Нет, это не так.NSMethodSignature не кодирует селектор.Вместо этого он кодирует сигнатуру метода.Это означает такие вещи, как тип и количество аргументов.Это также не будет работать правильно.Если кто-то попытается вызвать метод типа -setInteger:, который принимает NSUInteger, он будет передан вашему методу -say:, который ожидает NSString*.Но он не получит NSString*, он получит NSUInteger, и любая попытка разыменования приведет к краху (если только он не равен 0).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...