我想通过打印选择器和参数来拦截发送到代理对象的消息。即使代理没有实现它们并且没有目标对象。请帮忙。我查看了几个选项和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
谢谢谢谢
答案 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。