0

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

谢谢,谢谢

4

1 回答 1

3

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

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

但是,您可以有效地消除所有编译器警告。如果你消除了所有编译器警告——所有“方法 foo:bar: has can't be found”类型的警告——那么这意味着编译器确实有足够的信息,你可以用代理做任何你想做的事情。

此外(当我更多地阅读您的问题时),无需在代理上实现任何方法。代理可以很高兴地将任何方法调用转发到 NSInvocation。如果写得正确,您可以让代理代替任何对象而不会出现问题。

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

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

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

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

于 2009-11-29T05:10:49.383 回答