Objective-C va_list和选择器

时间:2010-01-26 06:06:56

标签: objective-c selector variadic-functions

是否可以对使用变量参数列表的方法使用@selectorperformSelector:(或类似)?

我正在编写一个可以分配委托的类来覆盖默认行为。在存在委托select方法的情况下,对该类的实例进行的调用将转发到相同的相应委托方法,其中一些方法使用变量参数列表。

因此,例如,我需要能够创建检索SEL引用并使用以下方法向委托对象发送消息:

- (void)logEventWithFormat:(NSString *)format, ... {
    va_list argList;
    id del = self.delegate;
    if (del != nil && 
        [del conformsToProtocol:@protocol(AProtocolWithOptionalMethods)] &&
        [del respondsToSelector:@selector(logEventWithFormat:)])
    {
        // Perform selector on object 'del' with 'argList'
    }
}

我假设这是不可能的,因此基金会框架中的类似方法声明 - 在NSString

- (id)initWithFormat:(NSString*)format, ...;

- (id)initWithFormat:(NSString *)format arguments:(va_list)argList;

我认为我希望委托的协议应建议实施:

- (void)logEventWithFormat:(NSString *)format arguments:(va_list)argList;

所以我可以使用选择器@selector(logEventWithFormat:arguments:)来调用:

[del performSelector:@selector(logEventWithFormat:arguments:) 
          withObject:format
          withObject:argList];

我只是想知道我是否遗漏了一些东西,或者想要实现我想要的目标?

4 个答案:

答案 0 :(得分:4)

您可以将任何想要的内容传递到运行时函数objc_msgSend

objc_msgSend(del, @selector(logEventWithFormat:arguments:), format, argList);

这是发送手动构建的消息的最强大方式。

但是,您不清楚是否需要以这种方式执行调用。正如KennyTM指出的那样,在您拥有的代码中,您可以直接调用该方法。

答案 1 :(得分:2)

您无法使用-performSelector:withObject:withObject:,因为va_list根本不是“对象”。您需要使用NSInvocation

或者直接致电

[del logEventWithFormat:format arguments:argList];

答案 2 :(得分:2)

据我所知,无法做到。您无法使用-performSelector:withObject:withObject:,因为@KennyTM指出,va_list不是对象。

但是,您也无法使用NSInvocationThe documentation straight up says so:

  

NSInvocation不支持   用任何一种方法调用方法   可变数量的参数或联合   参数。

由于这两种方式都是通过选择器调用方法,并且似乎都不起作用,我将继续使用“无法完成”的答案,除非您直接调用该方法并传递{{ 1}}作为一个论点。

也许@bbum会出现并进一步启发我们。 =)

答案 3 :(得分:0)

我之前没有这样做,但我经常使用的简单解决方案是为withObject参数打包/取消装入NSMutableArray或NSMutableDictionary。