打印发送到forwardInvocation的参数:NSProxy的子类

时间:2009-11-29 02:26:23

标签: iphone objective-c cocoa proxy-classes objective-c-runtime

我想通过打印选择器和参数来拦截发送到代理对象的消息。即使代理没有实现它们并且没有目标对象。请帮忙。我查看了几个选项和Apple文档,但他们认为您已经知道了目标对象。我想干净利落地做这件事,没有记忆问题。

 @implementation MyProxy

    -(void)forwardInvocation:(NSInvocation*)anInvocation
        {

        // at this point I would

         //like to fetch the arguments and put on an array 
         NSMutableArray *myArgs = .....;
         NSLog(@"Invoking selector %@", theSelector);
         NSLog (myArgs); // this should print me the list of arguments to the method
        }
@end
         // e.g 
            MyProxy *proxy = [[MyProxy alloc] init];
            [proxy SendMeAnyThing: @"hello"]; // this should print me arguments 
        or [proxy add: 12 to: 89 sub: 89]; // should print the arguments

谢谢谢谢

1 个答案:

答案 0 :(得分:3)

参数几乎是任何可以传递给方法的C类型,包括Objective-C类型。因此,它们不能用数组表示。

请注意,调用未在任何地方声明的方法没有任何意义。具体来说,编译器不知道如何在调用站点对参数进行编码以进行有效的C函数调用(方法调用实际上只是对objc_msgSend()或变量的C函数调用)。那么,回答你的“任何方法,即使它不存在”的问题;不,你做不到。

但是,您可以有效地消除所有编译器警告。如果你消除所有编译器警告 - 所有“方法foo:bar:找不到”类型警告 - 那么这意味着编译器 有足够的信息,你可以做任何事情想要代理。

此外(正如我在你的问题中读到的更多),没有必要在代理上实现任何方法。代理可以非常愉快地转发到NSInvocation任何方法调用。如果写得正确,您可以让代理站在任何对象中而不会出现问题。

您需要做的是使用NSInvocation的API枚举参数,取出类型然后相应地解码每个参数并正确打印。

您可以通过在NSInvocation实例的方法签名上调用numberOfArguments来获取参数数量(可以通过methodSignature方法获取签名)。

然后,遍历参数并在方法签名上调用getArgumentTypeAtIndex:以获取类型。然后,您很可能会在类型编码上写一个switch()语句,然后调用getArgument:atIndex:并根据类型进行适当的解码。

注意,参数0是self,参数1是_cmd;被调用的方法的SEL。