5

当一个对象调用另一个对象的方法时,Objective-C 使用复杂的消息传递系统。我想知道是否有可能在被调用的方法中确定调用对象是什么?

例如:

@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

为了使断言在执行时通过,我可以在注释行中写些什么performTest

4

4 回答 4

11

不是运行时。所有发送的消息最终都会按照objc_msgSend(id receiver, SEL selector, /*method arguments*/...). 如您所见,没有传递有关发送消息的对象的信息。可能通过遍历堆栈来确定调用对象,但这种方式很疯狂。sender判断谁调用了该方法的唯一实用方法是像所有 IBAction 方法一样给它一个参数。

于 2009-07-12T02:24:57.900 回答
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]);
于 2012-03-07T14:49:17.040 回答
2

不,你无法确定是什么物体在呼唤你。好吧,从技术上讲,可能可以绕过堆栈回溯,但对于实际代码来说肯定不实用。

如果您查看大多数委托方法,您会发现标准委托调用格式如下所示:

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

请注意窗口(调用者)如何作为第一个参数传递,以及“窗口”如何作为方法名称的第一部分。在最后一种情况下,窗口调用者隐含在 NSNotification 中(notification.object 是窗口)。

于 2009-07-12T02:44:48.587 回答
2

您可以尝试从中派生您自己的类,该类NSInvocation带有调用者信息。或者围绕 NSInvocation 包装一个类,重新实现其中的一些调用。

于 2009-07-12T10:23:46.210 回答