2011-04-07 4 views
10

정보가 invocationWithMethodSignature을 통해 이미 전달 된 경우 NSInvocation 개체에서 setSelector 메서드를 호출해야하는 이유를 이해할 수 없습니다. 우리가 [invocation setSelector:someSelector]; 다시 [SomeObject instanceMethodSignatureForSelector: someSelector];에 선택기를 통과NSInvocation 클래스에서 setSelector 메서드의 용도는 무엇입니까?

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]; 

주의 사항 :

우리가 다음을 수행 NSInvocation 객체를 생성합니다.

내가 누락 된 자료가 있습니까?

+1

+1 - 이미 100 만 번도 묻지 않았으며 (응답 된) 질문을보기에 좋으며, 해독 할 수없는 인스턴트 메시지 전문 용어로 작성되지 않았습니다. :-) –

+0

하나의 작은 점 :'signature = [SomeObject instanceMethodSignatureForSelector : someSelector];'는'signature = [[SomeObject class] instanceMethodSignatureForSelector : someSelector];이어야합니다. 또는 signature = [SomeObject methodSignatureForSelector : someSelector]; ' – Brynjar

답변

8

서명은 선택자가 아닙니다. 선택자는 메시지의 이름입니다. 서명은 매개 변수와 반환 값을 정의합니다. 동일한 서명으로 많은 선택자를 가질 수 있으며 그 반대의 경우도 가능합니다. NSMethodSignature을 보면 -selector 메서드가 없음을 알 수 있습니다. 시그너처는 특정 선택자를 가지고 다니지 않습니다.

는 그들은 같은 선택 @selector(setLocation:),하지만 서로 다른 서명이

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

다음 고려하십시오.

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

이들은 동일한 서명이지만 다른 선택자입니다.

Selectors ObjC 프로그래밍 언어에서이 이해하기위한 유용한 참조가 될 수 있습니다.

+0

당신이 말하는 것을 얻는 동안, 언어에 약간의 중복이있는 것 같습니다. 선택기를 두 번 (시그니처에 한 번, 한 번 호출 인스턴스에 한 번) 설정하고 있습니다. 필자는 개인적으로 (IMHO) 서명에서 selector (someSelector에서 정의 된 경우)를 도출하는 것이 더 효율적이라고 생각합니다. – haroldcampbell

+0

서명에서 선택자를 파생시킬 수 없습니다. 타겟을 물어 봄으로써 타겟과 셀렉터에서 서명을 파생시킬 수 있습니다 (새로운 메소드와 클래스는 런타임에 생성 될 수 있으므로 컴파일 타임에 결정할 수 없음).여러분은'+ invocationWithTarget : selector : arguments :'shortcut 메소드가있을 수 있습니다. (우리 팀은 비슷한 것을 추가하는 카테고리를 가지고 있습니다.) 호출하는 코드를 호출하기 때문에 더 효율적이지는 않지만 조금 더 편리 할 것입니다. –

3

메소드 서명은 리턴 유형과 인수의 수 및 유형만을 정의합니다. 선택기 이름에 대해서는 아무 것도 포함하지 않습니다. 예를 들어, 이러한 방법은 모두 가진 다른 선택기에도 불구하고, 동일한 서명이 :

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

이 측면 응답의 종류,하지만 당신은 다음과 같은 작업을 수행 할 수 있다는 사실은 나를 방법 사이의 더 나은 분리를 이해하는 데 도움 서명 및 선택자. 및 UIPopoverController의 dismissPopoverAnimated :

이 코드는

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 때문에

보기 컨트롤러 내에서 모두가 BOOL 인수를 void를 반환, 당신은 하나의 선택기를 사용하여 메소드 서명을 만들 수 있지만 호출을 보낼 수 있습니다 다른 사람에게.