2009-07-12 5 views
6

Objective-C는 한 개체가 다른 개체의 메서드를 호출 할 때 정교한 메시지 전달 시스템을 사용합니다. 호출 된 메서드 내에서 호출하는 개체가 무엇인지 판단 할 수 있는지 알고 싶습니다. 예를 들어Objective-C 런타임 기능을 사용하여 메소드가 호출 된 위치를 확인할 수 있습니까?

:

내가 performTest을 실행할 때 주장 패스를 만들기 위해 주석 줄을 쓸 수 무엇
@implementation callingClass 
- (void)performTest 
{ 
    calledObject = [[[calledClass alloc] init] autorelease]; 
    id result = [calledObject calledMethod]; 

    assert(result == this); 
} 
@end 

@implementation calledClass 
- (id)calledMethod 
{ 
    id objectThatCalledThisMethod = ... // <-- what goes here? 

    return objectThatCalledThisMethod; 
} 
@end 

?

답변

11

런타임에는 없습니다. 모든 메시지 전송은 궁극적으로 objc_msgSend(id receiver, SEL selector, /*method arguments*/...) 행을 따라 함수 호출로 해결됩니다. 보시다시피 메시지를 보내는 개체에 대한 정보는 전달되지 않습니다. 스택을 걷는 것으로 호출 객체를 결정할 수는 있지만, 그런 식으로 광기가 있습니다. 호출자에게이 메서드를 호출하는 유일한 방법은 모든 IBAction 메서드와 마찬가지로 sender 인수를 지정하는 것입니다.

2

아니요, 어떤 개체가 호출되었는지 확인할 수 없습니다. 글쎄, 기술적으로, 스택 백 트레이스 (back trace)를 훑어 볼 수도 있지만, 실제 코드에서는 실용적이지 않습니다. 창 (발신자)가 첫 번째 인수로 전달하는 방법과 방법

- (NSSize) windowWillResize:(NSWindow *)window toSize:(NSSize)proposedFrameSize; 
- (BOOL) windowShouldClose:(id)window; 
- (void) windowWillMove:(NSNotification *)notification; 

참고 : 대리자 메서드의 대부분을 보면

, 표준 위임 호출 형식은 다음과 같이 볼 수 있습니다 "window"는 메서드 이름의 첫 번째 부분입니다. 마지막 경우, 윈도우 호출자는 NSNotification (notification.object가 윈도우 임)에 함축되어있다.

2

발신자 정보를 가지고있는 NSInvocation에서 나만의 수업을 시도해 볼 수 있습니다. 또는 거기에있는 호출 중 일부를 다시 구현하는 NSInvocation 주변의 클래스를 래핑하십시오.

+0

있는 NSInvocation 또한 발신자에 대한 아무것도하지 않습니다 - 단지 목표, 선택, 및 인수를. –

+0

그 이유는 새 클래스를 파생 시키거나 주위에 배치하는 것이 좋습니다. 이는 발신자를 호출 함수에 전달하거나 수신자 측에서 정보를 가져올 수있는 데이터 구조를 만들 수있는 일관된 방법을 제공 할 수 있습니다. 그가 성취하려고하는 것에 달려있다. –

4

나는이 도움이되기를 바랍니다 :

NSString *sourceString = [[NSThread callStackSymbols] objectAtIndex:1]; 
    // Example: 1 UIKit        0x00540c89 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1163 
    NSCharacterSet *separatorSet = [NSCharacterSet characterSetWithCharactersInString:@" -[]+?.,"]; 
    NSMutableArray *array = [NSMutableArray arrayWithArray:[origen componentsSeparatedByCharactersInSet:separatorSet]]; 
    [array removeObject:@""]; 

    NSLog(@"Pila = %@", [array objectAtIndex:0]); 
    NSLog(@"Framework = %@", [array objectAtIndex:1]); 
    NSLog(@"Memory address = %@", [array objectAtIndex:2]); 
    NSLog(@"Class caller = %@", [array objectAtIndex:3]); 
    NSLog(@"Function caller = %@", [array objectAtIndex:4]); 
    NSLog(@"Line caller = %@", [array objectAtIndex:5]);