【问题标题】:Printing arguments sent to forwardInvocation: subclass of NSProxy打印发送到 forwardInvocation 的参数:NSProxy 的子类
【发布时间】:2009-11-29 02:26:23
【问题描述】:

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

感谢感谢

【问题讨论】:

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


    【解决方案1】:

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

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

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

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多