2011-04-07 2 views
10

Не понимаю, почему мы должны вызвать метод setSelector на объектах NSInvocation, когда эта информация уже передана через invocationWithMethodSignature.Какова цель метода setSelector в классе NSInvocation?

Для создания NSInvocation объекта мы делаем следующее:

SEL someSelector; 
NSMethodSignature *signature; 
NSInvocation *invocation; 

someSelector = @selector(sayHelloWithString:); 

//Here we use the selector to create the signature 
signature = [SomeObject instanceMethodSignatureForSelector:someSelector]; 
invocation = [NSInvocation invocationWithMethodSignature:signature]; 

//Here, we again set the same selector 
[invocation setSelector:someSelector]; 
[invocation setTarget:someObjectInstance]; 
[invocation setArgument:@"Loving C" atIndex:2]; 

Обратите внимание, что мы прошли селектор [SomeObject instanceMethodSignatureForSelector: someSelector]; и снова [invocation setSelector:someSelector];.

Есть ли что-то, что мне не хватает?

+1

+1 - Приятно видеть здесь вопрос, который еще не был задан (и ответил) уже миллион раз, и не написан на неразгаданном жаргоне мгновенных сообщений. :-) –

+0

Одна маленькая точка: 'signature = [SomeObject instanceMethodSignatureForSelector: someSelector];' должен быть либо 'signature = [[SomeObject class] instanceMethodSignatureForSelector: someSelector]; или signature = [SomeObject methodSignatureForSelector: someSelector]; ' – Brynjar

ответ

8

Подпись не является селектором. Селектор - это имя сообщения. Подпись определяет параметры и возвращаемое значение. У вас может быть множество селекторов с одной и той же подписью и наоборот. Если вы посмотрите на NSMethodSignature, вы заметите, что нет метода -selector; подписи не относятся к определенному селектору.

Рассмотрим следующий

- (void)setLocation:(CGFloat)aLocation; 
- (void)setLocation:(MyLocation*)aLocation; 

Они имеют один и тот же селектор @selector(setLocation:), но разные подписи.

- (void)setX:(CGFloat)x; 
- (void)setY:(CGFloat)y; 

У них такая же подпись, но разные селекторы.

Selectors Язык программирования ObjC может быть полезной ссылкой для понимания этого.

+0

Пока я получаю то, что вы говорите, на языке, похоже, немного избыточно. Я устанавливаю селектор дважды (один раз в сигнатуре и еще раз в экземпляре вызова). Я лично (IMHO) считаю, что было бы более эффективно либо выводить селектор (который в моем случае был определен в 'someSelector') из подписи. – haroldcampbell

+0

Вы не можете получить селектор от подписи. Вы можете получить подпись из целевого объекта и селектора, задав целевой объект (помните, что новые методы и классы могут быть созданы во время выполнения, вы не можете определить это во время компиляции).Вы правы, что может быть '+ invocationWithTarget: selector: arguments:' shortcut method (у моей команды есть категория, которая добавляет что-то подобное). Это было бы неэффективно, поскольку он просто вызывал код, который вы вызываете, но было бы немного более удобным. –

3

Подписи метода определяют тип возврата, а также количество и тип аргументов. Он не содержит ничего о имени селектора. Например, все эти методы имеют одинаковую сигнатуру, несмотря на наличие различных селекторов:

-(void) foo:(NSString*)fooString; 
-(void) bar:(NSString*)barString; 
-(void) baz:(NSString*)bazString; 
0

Это своего рода побочный ответ, но тот факт, что вы можете сделать следующее помогло мне лучше понять разделение между методом подписей и селекторов.

Этот код находится в View Controller

NSMethodSignature *sig = nil; 
sig = [[self class] instanceMethodSignatureForSelector:@selector(viewDidAppear:)]; 
NSInvocation *myInvocation = nil; 
myInvocation = [NSInvocation invocationWithMethodSignature:sig]; 

[myInvocation setTarget:_somePopoverController]; 
[myInvocation setSelector:@selector(dismissPopoverAnimated:)]; 
BOOL animate = YES; 
[myInvocation setArgument:&animate atIndex:2]; 
[myInvocation invoke]; 

С UIViewController в viewDidAppear: и UIPopoverController в dismissPopoverAnimated: как принять BOOL аргумент и возвращения недействительным, вы можете создать сигнатуру метода, используя один селектор, но послать вызов другому.

 Смежные вопросы

  • Нет связанных вопросов^_^