打印发送到forwardInitation的参数:NSProxy的子类
我想通过打印选择器和参数来拦截发送到代理对象的消息。即使代理没有实现它们并且没有目标对象。请帮忙。我已经查看了几个选项和 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
谢谢谢谢
I want to intercept messages sent to a proxy object by just printing the selector and arguments. Even if the proxy does not implement them and does not have a target object. Please help. I have looked at several options and Apple docs but they assume that you already know the target object. I want to do this cleanly without memory issues.
@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
Thanks thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
参数几乎可以是任何可以传递给该方法的 C 类型,包括 Objective-C 类型。因此,它们不能用数组表示。
请注意,调用未在任何地方声明的方法没有任何意义。非常具体地说,编译器不知道如何在调用站点对参数进行编码以进行有效的 C 函数调用(方法调用实际上只是对 objc_msgSend() 或其变体的 C 函数调用) 。因此,回答您的“任何方法,即使它不存在”的问题;不,你不能那样做。
但是,您可以有效地消除所有编译器警告。如果您消除所有编译器警告 - 所有“method foo:bar: has can't be find”类型警告 - 那么这意味着编译器确实有足够的信息,你可以做任何你想做的事想要一个代理。
此外(当我更多地了解你的问题时),不需要在代理上实现任何方法。代理可以非常愉快地将任何方法调用转发到 NSInitation 中。如果编写正确,您可以让代理代表任何对象而不会出现问题。
您需要做的是使用
NSInitation
的 API 枚举参数,找出类型,然后相应地解码每个参数并适当地打印。您可以通过在 NSInitation 实例的方法签名上调用
numberOfArguments
来获取参数数量(该签名可以通过methodSignature
方法获得)。然后,循环遍历参数并在方法签名上调用 getArgumentTypeAtIndex: 来获取类型。然后,您很可能会在类型编码上编写一个
switch()
语句,然后调用getArgument:atIndex:
并根据类型进行适当解码。请注意,参数 0 是 self,参数 1 是 _cmd;被调用方法的 SEL。
The arguments are of just about any C type, including Objective-C types, that may be passed to the method. Thus, they can't be represented in an array.
Note that invoking a method that is not declared anywhere doesn't make any sense. Quite specifically, the compiler has no idea how to encode the arguments at the call site to make a valid C function call (a method call is really just a C function call to
objc_msgSend()
or a variant). So, to answer your "any method, even if it doesn't exist" question; no, you can't do that.You can, however, effectively eliminate all compiler warnings. If you eliminate all compiler warnings -- all "method foo:bar: has can't be found" type warnings -- then that means the compiler does have enough information and you can do whatever the heck you want with a proxy.
Furthermore (as I read more into your question), there is no need to implement any method on the proxy. A proxy can quite happily forward-into-NSInvocation any method call. Written correctly, you can have a proxy stand in for any object without issue.
What you need to do is enumerate the arguments using the API of
NSInvocation
, sussing out the types and then decoding each argument accordingly and printing appropriately.You can grab the number of arguments by invoking
numberOfArguments
on the method signature of the NSInvocation instance (the signature can be had via themethodSignature
method).Then, loop through the arguments and call
getArgumentTypeAtIndex:
on the method signature to get the type. You would then most likely write aswitch()
statement on the type encoding to then callgetArgument:atIndex:
and decode appropriately based on type.Note that argument 0 is self and argument 1 is _cmd; the SEL of the method that was invoked.